1

我已经阅读了很多问题和答案,但我找不到我的问题的解决方案。当我从 NHibernate 1.2.1 迁移到 2.1.2 时,会出现问题。我有这个常见的错误:

对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例。类型:Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion,实体:Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion

NHibernate 配置:
<休眠>
          <add key="hibernate.show_sql" value="true" />
          <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
          <add key="方言" value="NHibernate.Dialect.MsSql2005Dialect" />
          <add key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle" />
          <add key="driver_class" value="NHibernate.Driver.SqlClientDriver" />
          <add key="connection.connection_string" value="..." />          
</休眠>

主类CRResidence的映射:

<?xml 版本="1.0" 编码="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
<class name="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidence, Mikro.FareOn.Modules.Cards.Interface" table="CR_Residence">
    <id name="Id" column="id" type="Int64" access="nosetter.camelcase" unsaved-value="0">
      <generator class="身份" />
    </id>
    <version name="VersionId" column="version_id" type="Int64" />
    <property name="IsDeleted" column="deleted" type="Boolean" not-null="true" />
    <property name="Name" column="name" type="String" not-null="true" />
    <many-to-one name="Region" column="region_id" cascade="none" class="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion, Mikro.FareOn.Modules.Cards.Interface"/>
    <property name="Postcode" column="postcode" type="String" not-null="true" />
    <many-to-one name="Country" column="residence_country_id" cascade="none" class="Mikro.FareOn.TransportOperator.Interface.BEC.TOResidenceCountry, Mikro.FareOn.TransportOperator.Interface"/>
  </class>
</hibernate-mapping>

与多对一相关的类之一:

<?xml 版本="1.0" 编码="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
  <class name="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion, Mikro.FareOn.Modules.Cards.Interface" table="CR_ResidenceRegion" >
    <id name="Id" column="id" type="Int64" access="nosetter.camelcase" unsaved-value="0">
      <generator class="身份" />
    </id>
    <version name="VersionId" column="version_id" type="Int64" />
    <property name="Name" column="name" type="String" not-null="true" />
    <property name="IsDeleted" column="deleted" type="Boolean" not-null="true" />
  </class>
</hibernate-mapping>

CRResidenceRegion 类的实现:

[可序列化]
    public class CRResidence : BussinesEntityComponentBase //这是一个类,它实现了Equals并定义了Id、VersionId、IsDeleted
    {
    字符串名称;
        字符串邮政编码;
    CRResidenceRegion 区域;
    TOResidenceCountry国家;

    #region 获取器/设置器

    ///
    /// 纳泽夫米斯塔
    ///
    公共字符串名称
    {
      获取{返回此名称;}
      设置 { this.name = value; }
    }
    ///
    /// 地区
    ///
    公共 CRResidenceRegion Region
    {
      得到
      {
        返回这个.region;
      }
      放
      {
        this.region = 值;
      }
    }
    ///
    /// 统计
    ///
    公共 TOResidenceCountry Country
    {
      得到
      {
        返回这个.country;
      }
      放
      {
        这个国家=价值;
      }
    }
    ///
    /// PSC
    ///
    公共字符串 邮政编码
    {
      得到{返回this.postcode; }
      设置 { this.postcode = value; }
    }
    公共字符串 PostcodeAndName
    {
      get { return String.Format("{0} - {1}", Postcode, Name); }
    }
    公共字符串 NameAndPostcode
    {
      get { return String.Format("{1} - {0}", Postcode, Name); }
    }
    #endregion
    ///
    /// Konstruktor objektu rezidence
    ///
    公共 CRResidence()
      : 根据()
    {
    }    
}

我尝试了所有类型的级联,但任何级联都无法正常工作。但就我而言,我更喜欢 cascade = "none"。我有客户端,通过在一个 NHibernate 会话中调用服务器端的方法来加载对象 CRResidenceRegion。加载 NHibernate 会话后关闭。客户端上的对象是正确的,数据库中的正确 ID 等等。然后给CRResidence对象赋值CRResidenceRegion对象。然后在服务器端调用方法:

使用 (PersistenceSession session = Registrator.OpenSession())
{
        ITransaction trx = session.BeginTransaction();
        尝试
        {          
          session.Update(居住地);
          //residence.Region = (CRResidenceRegion)session.Get(typeof(CRResidenceRegion),residence.Region.Id);    
          //residence.Country = (TOResidenceCountry)session.Get(typeof(TOResidenceCountry),residence.Country.Id);
          trx.Commit();
          log.Debug("CRResidence 更新。");
          返还居住地;
        }
        捕捉(例外前)
…………
      }

我有很多这样的对象,当我迁移到 NHibernate 2.1.2 时出现了这个问题。在某些情况下,在定义级联样式后效果很好(“无”和“全部”一样有效,我需要)。可能是 NHibernate 的配置文件中的问题。

问题的先前定义:当我尝试插入或更新 CRResidence 的实例时,出现关于未保存的瞬态错误的错误。CRResidenceRegion的Instance完全初始化了,包括Id,所以没有问题。我在 Id 上实现了 Equal 方法。我试图清除缓存,但没有帮助。当我将级联更改为保存更新时,它可以工作,但是 CRResidenceRegion 的记录是重复的。一种解决方案是在保存 CRResidence 之前,我在同一会话中从数据库中读取 CRResidenceRegion(在下面的代码中注释),但这是不可接受的。

似乎 NHibernate 可能已经失去了对 CRResidenceRegion 的引用,并认为它是新创建的,但事实并非如此。

4

3 回答 3

1

使用 Session.Load 方法而不是 Get 来初始化 CRResidenceRegion 实体。除非您访问其任何属性,否则这实际上不会进入数据库。

...
residence.Region = session.Load<CRResidenceRegion>(residence.Region.Id);         
session.Update(residence);
trx.Commit();
...
于 2011-06-13T15:05:09.320 回答
0

我找到了我的问题的解决方案。问题出在 version_id 中,我在 CR_ResidenceRegion 的映射文件中添加了一个未保存的值。

<version name="VersionId" column="version_id" type="Int64" unsaved-value="0" />

我认为他们更改了未保存值的默认值。

谢谢大家的帮助

于 2011-06-17T11:55:59.217 回答
0

这可能是因为它来自另一个会话。

试试session.Merge()吧。

于 2011-06-13T12:24:44.640 回答