10

I have a hierarchical entity, which references it self as a parent. I need to do the mapping only via ids, not via entity instances (the reason is too complicated to explain). So I defined the entity this way:

class Item {

    @Id
    private String id;

    @ManyToOne(targetEntity = Item.class)
    @JoinColumn(name = "PARENT_ID", nullable = true)
    private String parentId;

}

This seems to work fine. The foreign key constraint is created correctly in database. But when I execute the following query:

SELECT i FROM Item i WHERE i.parentId = :parentId

I get this exception (the interesting parts are in bold):

org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.example.dom.Item.id at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:192) at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:346) at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746) at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4465) at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:243) at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:293) at org.hibernate.type.EntityType.getIdentifier(EntityType.java:537) at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:174) at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:67) at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:616) at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1901) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1862) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839) at org.hibernate.loader.Loader.doQuery(Loader.java:910) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) at org.hibernate.loader.Loader.doList(Loader.java:2554) at org.hibernate.loader.Loader.doList(Loader.java:2540) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) at org.hibernate.loader.Loader.list(Loader.java:2365) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300) at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103) at com.example.dao.ItemDao.findChildrenByParentId(ItemDao.java:43) at com.example.dao.ItemDao$$FastClassBySpringCGLIB$$51b04ce9.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ... 47 more Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:169) ... 76 more

It seems like Hibernate is trying to work with property parentId as if it was of type Item, not String.

Any ideas?

Also please do not advise me to use lazy loading. It is not feasible in my situation (again, too complicated to explain).

Jardo
  • 1,939
  • 2
  • 25
  • 45

3 Answers3

3

Associations use entity references (which would require you to use the real object Item in this case) If you want to use plain ID columns, then you are saying you don't want hibernate to manage them, just remove the association annotations.

leeor
  • 17,041
  • 6
  • 34
  • 60
  • But how am I supposed to create the foreign key constraint then? I could use an external DDL script but that's clumsy. – Jardo Sep 23 '15 at 09:20
  • 2
    nothing is stopping you from having a constaint in the database. hibernate just gives you the benefit of hbm2ddl – leeor Sep 23 '15 at 13:20
0

Try define the id column, for example try this.

@Column(name="id")
hide
  • 92
  • 3
-1

As I understand your problem, this may useful.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private String id;


@ManyToOne
@JoinColumn(name = "parent_id",nullable = true)
private Item item;
samith kumarasingha
  • 294
  • 1
  • 3
  • 16