Hibernate: foreign key without entity class, only by id

元气小坏坏 提交于 2020-12-05 05:13:48

问题


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


回答1:


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.




回答2:


Try define the id column, for example try this.

@Column(name="id")



回答3:


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;


来源:https://stackoverflow.com/questions/32722941/hibernate-foreign-key-without-entity-class-only-by-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!