【问题标题】:Return of the "object references an unsaved transient instance"返回“对象引用了未保存的瞬态实例”
【发布时间】:2011-08-16 09:39:30
【问题描述】:

我有 2 个类,ForecastCost,它们之间定义了多对多关系。我们现在在链接表中添加了一个“订单”列(因此我们的客户可以在Forecast 中指定Costs 的订单)。为了在我们的映射中反映这一点,我们创建了一个新实体ForecastCost,并将ForecastCost 之间的多对多替换为Forecast 1-* ForecastCost *-1 Cost

映射如下所示:

Forecast.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  namespace="FinRep" assembly="FinRep">
  <class name="Forecast" table="FORECAST" polymorphism="implicit">
    <id name="Id" column="PKFORECAST" type="long" access="field.camelcase" unsaved-value="0"><!-- ... --></id>

    <!-- ... -->

    <bag name="KostComponenten" table="FORECASTCOST" access="field.camelcase" lazy="false" cascade="save-update">
      <key column="FKFRBFORECAST"></key>
      <one-to-many class="ForecastCost" />
    </bag>
  </class>
</hibernate-mapping>

ForecastCost.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  namespace="FinRep" assembly="FinRep">
    <class name="ForecastCost" table="FORECASTCOST">
        <composite-id name="ForecastCostId" class="FinRep.ForecastCostKey, FinRep">
            <key-many-to-one name="Forecast" column="FKFORECAST" lazy="false" class="FinRep.Forecast, FinRep" />
            <key-many-to-one name="Cost" column="FKCOST" lazy="false" class="FinRep.Cost, FinRep" />
        </composite-id>

        <property name="Order" column="ORDER" />
    </class>
</hibernate-mapping>

首先,Forecast 映射中包上的“级联”属性未设置,因此当我尝试保存链接了一些Costs 的Forecast 时,我会(理所当然地如此)收到一条错误消息,指出无法从数据库中检索到相关的 ForecastCost 对象。我认为添加 'cascade' 属性可以解决这个问题,但现在当我尝试保存 Forecast#1(例如)时,我收到一个异常,提示 object references an unsaved transient instance - save the transient instance before flushing type=Forecast entity=1。

我认为正在发生的事情是它试图保存 Forecase,并且通过这样做它还尝试保留所有链接到它的 ForecastCost/Cost 对象,但 ForecastCost 对象也有一个链接回到我们正在保存的Forecast 实体(但尚未保存,因此是暂时的),因此它会出错。

我应该怎么做才能解决这个问题?

【问题讨论】:

  • 我刚刚发现的东西 - 我只在使用 SaveOrUpdateCopy 时收到错误。使用SaveOrUpdate 时一切正常。

标签: c# nhibernate nhibernate-mapping


【解决方案1】:

只是另一种方法,可以让您继续上课。

class ForeCast
{
    // public virtual ICollection<Kost> KostComponenten { get; set; } // old
    public virtual IList<Kost> KostComponenten { get; set; }          // new
}

并映射它:

<list name="KostComponenten" table="FORECASTCOST" access="field.camelcase" lazy="false" cascade="save-update">
  <key column="FKFRBFORECAST"/>
  <index column="order"/>
  <many-to-many class="ForecastCost" />
</bag>

那么订单在列表中,你可以做KostComponenten.Insert(...)KostComponenten.Add(...)等等

【讨论】:

  • 那是我最初的计划,但我读到 NHibernate 不会在顺序序列中有间隙(例如 1、2、4、5)或有重复(0、0 , 0) -- 一定会发生的事情,我可以在客户端订购时轻松解决......
  • @efdee 您如何维护订单?如果您使用 IList 的 addinsertremove,则不应有 0,0,0,并且间隙仅被视为列表中的空指针
  • 首先,我们已经在数据库中有很多条目,默认情况下它们的顺序现在将设置为 0,仅此一项就已经是一个问题了。其次,我不希望删除导致对所有其他行的更新(以修复它们的索引)。现在我的用例不实用。
  • 注意:我在我的一个项目中遇到了同样的问题,我只是在我的更新脚本中定义了一个 sql 语句,它将列表索引列初始化为递增数字。没错,如果您在预测中对成本进行大量更新排序,那么它是不切实际的
猜你喜欢
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 2019-01-14
  • 2012-03-21
  • 2016-06-02
  • 2013-01-04
相关资源
最近更新 更多