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 之前保存瞬态实例 [重复]

在刷新之前保存瞬态实例,或者将属性的级联操作设置为使其自动保存的内容

HIbernate - 对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例

对象引用未保存的瞬态实例:在刷新之前保存瞬态实例[重复]