内心的冬眠行为中有一些我不明白的行为。
我有一个正常 hibernate配置的类,其中另一个参考。
我的主要课程
<hibernate-mapping package="com.my.package">
<class name="MyClass" table="MY_TABLE">
<id name="id" column="ID">
<generator class="sequence">
<param name="sequence">SEQ_MY_TABLE</param>
</generator>
</id>
<!-- reference -->
<many-to-one class="MyReferenceClass" fetch="select" name="myReference">
<column name="ID" not-null="true"/>
</many-to-one>
<!-- some other properties ... -->
.
.
</class>
</hibernate-mapping>
下面的参考类
<hibernate-mapping package="com.my.package">
<class name="MyReferenceClass" table="MY_REFERENCE_CLASS">
<id name="id" type="long">
<column name="ID" precision="22" scale="0" />
<generator class="sequence" />
</id>
</class>
<!-- Some propeties -->
.
.
</hibernate-mapping>
我在这个参考表中有一些行:
id,property1,property2
0 val1x val2x
1 val1y val2y
2 val1z val2z
。
我的问题是,当我尝试插入一个新的MyClass实例时,它引用了ID为1,2的MyReferenceClass,...,我没有问题。但是当我尝试插入id为0的那个时,我得到了以下例外:
org.hibernate.PropertyValueException: not-null property references a null or transient value: com.my.package.MyClass.myReference
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
我通过在MyReferenceClass.hbm.xml中将生成器类从序列更改为已分配来解决问题:
<hibernate-mapping package="com.my.package">
<class name="MyReferenceClass" table="MY_REFERENCE_CLASS">
<id name="id" type="long">
<column name="ID" precision="22" scale="0" />
<generator class="assigned" />
</id>
</class>
<!-- Some propeties -->
.
.
</hibernate-mapping>
问题在于我不知道为什么它只在我的id = 0而不是每次都没有时才起作用。
在Hibernate Framework的这一部分,我不明白哪种机制?
PS:我知道我的第一个文件中的序列是假的,因为我们这里没有序列,这实际上是一个旧的遗留代码,我正在进化,但我不明白为什么它以前工作过。答案 0 :(得分:0)
看起来MyReferenceClass的id映射的unsaved-value属性默认为0,并且没有为MyClass启用级联更新。
当您添加id为unsaved-value以外的对象时,Hibernate会假定您引用现有行。当您添加id与unsaved-value匹配的对象时,Hibernate会假定该实体是瞬态的,需要持久保存才能从序列中获取新值。并且由于您的集合不是级联的,因此Hibernate假定引用是针对现有的非瞬态实体。
将发电机更改为&#34;已分配&#34;意味着你承担了填充id的全部责任,而Hibernate不必担心它。
要使序列生成器能够正常工作,您可以在将对象添加到集合之前保存对象,或者在集合的映射上设置级联。