Java Hibernate:不带实体类的外键,仅按id
我有一个分层实体,它将自身作为父实体引用。我只需要通过ID进行映射,而不需要通过实体实例(原因太复杂,无法解释)。所以我这样定义实体:Java Hibernate:不带实体类的外键,仅按id,java,entity-framework,hibernate,foreign-keys,Java,Entity Framework,Hibernate,Foreign Keys,我有一个分层实体,它将自身作为父实体引用。我只需要通过ID进行映射,而不需要通过实体实例(原因太复杂,无法解释)。所以我这样定义实体: class Item { @Id private String id; @ManyToOne(targetEntity = Item.class) @JoinColumn(name = "PARENT_ID", nullable = true) private String parentId; } 这似乎很有效。已
class Item {
@Id
private String id;
@ManyToOne(targetEntity = Item.class)
@JoinColumn(name = "PARENT_ID", nullable = true)
private String parentId;
}
这似乎很有效。已在数据库中正确创建外键约束。但当我执行以下查询时:
SELECT i FROM Item i WHERE i.parentId = :parentId
我得到这个例外(有趣的部分用粗体表示):
org.hibernate.PropertyAccessException:IllegalArgumentException调用com.example.dom.Item.id的getter时发生
位于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.procedue(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多
Hibernate似乎正在尝试使用属性parentId,就好像它是Item类型,而不是String类型一样
有什么想法吗
也请不要建议我使用延迟加载。这在我的情况下是不可行的(同样,太复杂了,无法解释)。关联使用实体引用(在本例中,这将要求您使用真实对象
项
),如果您希望使用普通ID列,那么您是说您不希望hibernate管理它们,只需删除关联注释。尝试定义id列,例如,尝试以下操作
@Column(name="id")
我理解你的问题,这可能有用
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private String id;
@ManyToOne
@JoinColumn(name = "parent_id",nullable = true)
private Item item;
但是我应该如何创建外键约束呢?我可以使用外部DDL脚本,但这很笨拙。没有什么可以阻止您在数据库中使用constaint。hibernate只是为您提供了HBM2DDL的好处,这正是我不想要的。请尝试更改join column部分,如@column(name=“parent_id”)私有字符串parentId;可能重复的