问题描述
我有一个层次结构实体,该实体将其自身称为父级.我只需要通过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:调用com.example.dom.Item.id的getter时发生了IllegalArgumentException 在org.hibernate.property.BasicPropertyAccessor $ BasicGetter.get(BasicPropertyAccessor.java:192)在org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:346)在org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746)在org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4465)在org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:243)在org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:293)在org.hibernate.type.EntityType.getIdentifier(EntityType.java:537)在org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:174)在org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:67)在org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:616)在org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1901)在org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1862)在org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839)在org.hibernate.loader.Loader.doQuery(Loader.java:910)在org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355)在org.hibernate.loader.Loader.doList(Loader.java:2554)在org.hibernate.loader.Loader.doList(Loader.java:2540)在org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370)在org.hibernate.loader.Loader.list(Loader.java:2365)在org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497)在org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)在org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236)在org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300)在org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)在com.example.dao.ItemDao.findChildrenByParentId(ItemDao.java:43)在com.example.dao.ItemDao $$ FastClassBySpringCGLIB $$ 51b04ce9.invoke()在org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)在org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)在org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)...更多47原因:java.lang.IllegalArgumentException:对象不是声明类的实例在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)在java.lang.reflect.Method.invoke(Method.java:597)在org.hibernate.property.BasicPropertyAccessor $ BasicGetter.get(BasicPropertyAccessor.java:169)...另外76个
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 moreCaused 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
似乎Hibernate试图使用属性parentId,就好像它是Item类型,而不是String类型.
It seems like Hibernate is trying to work with property parentId as if it was of type Item, not String.
有什么想法吗?
也请不要建议我使用延迟加载.在我的情况下这是不可行的(再次,太复杂了,无法解释).
Also please do not advise me to use lazy loading. It is not feasible in my situation (again, too complicated to explain).
推荐答案
关联使用实体引用(在这种情况下,将要求您使用真实的对象 Item
)如果要使用纯ID列,则表示您不希望休眠管理它们,只需删除关联注释.
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.
这篇关于休眠:没有实体类的外键,仅按ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!