NHibernate 错误 - 在刷新之前保存瞬态实例
Posted
技术标签:
【中文标题】NHibernate 错误 - 在刷新之前保存瞬态实例【英文标题】:NHibernate Error - Save the Transient Instance Before Flushing 【发布时间】:2009-11-03 12:55:35 【问题描述】:我已经成功编写了一个系统,该系统包含一个带有子订单行的订单,使用订单的级联更新来保存订单行。在下一次迭代中,我想将订单行与派送类相关联。这看起来很简单——将一个可为空的 DespatchID 列添加到订单行表作为 Despatch 表的外键。但是,当我将其添加到映射中并保存订单对象时未在订单行上设置发货时,我收到错误“对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例”。
如果我删除订单行和发货之间的关联,它会保存 OK。我只能假设错误是因为它试图保存不存在的发货。
这是映射(订单行类称为 OrderProductAmount):
<class name="NHS.WebTeam.PandemicFluDistribution.Order, NHS.WebTeam.PandemicFluDistribution" table="[Order]" lazy="false" optimistic-lock="version" where="Deleted=0" >
<id name="ID" type="Int32" column="OrderID" unsaved-value="0">
<generator class="hilo">
<param name="table">NHibernateHiLo</param>
<param name="column">NextValue</param>
<param name="max_lo">100</param>
</generator>
</id>
<version column="version" name="Version"/>
<property name="Deleted" column="Deleted" />
<property name="DateEntered"></property>
<property name="RequiredDeliveryDate"></property>
<many-to-one name="Practice" column="PracticeID"></many-to-one>
<set name="OrderProductAmounts" access="field.camelcase-underscore" inverse="true" cascade="all-delete-orphan" lazy="true">
<key column="OrderID"></key>
<one-to-many class="NHS.WebTeam.PandemicFluDistribution.OrderProductAmount, PandemicFluDistribution" />
</set>
</class>
<class name="NHS.WebTeam.PandemicFluDistribution.OrderProductAmount, NHS.WebTeam.PandemicFluDistribution" table="OrderProductAmount" lazy="false" optimistic-lock="version" where="Deleted=0" >
<id name="ID" type="Int32" column="OrderProductAmountID" unsaved-value="0">
<generator class="hilo">
<param name="table">NHibernateHiLo</param>
<param name="column">NextValue</param>
<param name="max_lo">100</param>
</generator>
</id>
<version column="version" name="Version"/>
<property name="Deleted" column="Deleted" />
<many-to-one name="Order" column="OrderID"></many-to-one>
<many-to-one name="ProductAmount" column="ProductAmountID"></many-to-one>
<many-to-one name="Despatch" column="DespatchID" cascade="none" not-null="false"></many-to-one>
</class>
<class name="NHS.WebTeam.PandemicFluDistribution.Despatch, NHS.WebTeam.PandemicFluDistribution" table="Despatch" lazy="false" optimistic-lock="version" where="Deleted=0" >
<id name="ID" type="Int32" column="DespatchID" unsaved-value="0">
<generator class="hilo">
<param name="table">NHibernateHiLo</param>
<param name="column">NextValue</param>
<param name="max_lo">100</param>
</generator>
</id>
<version column="version" name="Version"/>
<property name="Deleted" column="Deleted" />
<property name="DateDespatched"></property>
<property name="RequiredDeliveryDate"></property>
<many-to-one name="Practice" column="PracticeID"></many-to-one>
<set name="OrderProductAmounts" access="field.camelcase-underscore" inverse="true" cascade="none" lazy="true">
<key column="DespatchID"></key>
<one-to-many class="NHS.WebTeam.PandemicFluDistribution.OrderProductAmount, PandemicFluDistribution" />
</set>
</class>
创建订单的代码基本上是这样的:
Dim practice = ... get relevant Practice ...
Dim productAmount = ... get relevant ProductAmount ...
Dim newOrder as Order = new Order(practice)
newOrder.AddProductAmount(new OrderProductAmount(newOrder, productAmount)
OrderDAO.Save(newOrder)
有人有什么想法吗?
【问题讨论】:
我很确定您在这里引用了一个调度类。显示创建或加载和存储实例的代码... 我添加了一个近似的代码来创建问题的顺序。我还没有编写将发货添加到订单行的部分,所以我不会想到它们之间会有关联。 当您创建 Order 对象时,您为 Despatch 属性分配了什么值?如果它不是 NULL,而是一个 Id = 0 的 Despatch 对象,我认为 NHibernate 会抛出该异常。 我已经调试了代码,当订单被保存时,订单行上的 Despatch 肯定是 NULL。 【参考方案1】:正如上面的 cmets 所暗示的那样(非常感谢),Despatch 听起来有些不对劲。而且,事实证明,Despatch 并不是问题所在。虽然由于某种原因它在我添加它之前就起作用了。
我通过向 Order 的 OrderProductAmount 链接添加 cascade="all" 解决了这个问题:
<many-to-one name="Order" column="OrderID" cascade="all"></many-to-one>
引发的错误是在保存 OrderProductAmount 时 Order 仍然是瞬态的。这非常令人困惑,因为我保存的是 Order 而不是 OrderProductAmount - OrderProductAmounts 仅通过 Order 的级联保存。
所以,如果有人知道为什么会这样,我很想知道。
【讨论】:
感谢您分享您的答案。将 .Cascade.All() 添加到 Foreign 表引用确实为我解决了上述错误。以上是关于NHibernate 错误 - 在刷新之前保存瞬态实例的主要内容,如果未能解决你的问题,请参考以下文章
Grails - 在刷新 grails 错误之前保存瞬态实例?
使用 Fluent NHibernate AutoMapping 进行级联保存
对象引用未保存的瞬态实例 - 在刷新休眠 JPA 之前保存瞬态实例 [重复]
在刷新之前保存瞬态实例,或者将属性的级联操作设置为使其自动保存的内容