Jardo
Jardo

Reputation: 2093

Hibernate: foreign key without entity class, only by id

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).

Upvotes: 10

Views: 4851

Answers (3)

samith kumarasingha
samith kumarasingha

Reputation: 294

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;

Upvotes: -1

hide
hide

Reputation: 92

Try define the id column, for example try this.

@Column(name="id")

Upvotes: 0

leeor
leeor

Reputation: 17761

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.

Upvotes: 3

Related Questions