1

多くの質問と回答を読みましたが、問題の解決策を見つけることができませんでした。この問題は、NHibernate1.2.1から2.1.2に移行したときに発生します。この一般的なエラーがあります:

オブジェクトは保存されていない一時インスタンスを参照します-フラッシュする前に一時インスタンスを保存します。タイプ:Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion、エンティティ:Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion

NHibernate構成:
<nhibernate>
          <add key = "hibernate.show_sql" value = "true" />
          <add key = "hibernate.connection.provider" value = "NHibernate.Connection.DriverConnectionProvider" />
          <add key = "dialect" 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 = "..." />          
</ nhibernate>

メインクラスCRResidenceのマッピング:

<?xml version = "1.0" encoding = "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 = "identity" />
    </ 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-マッピング>

そして、多対多の関係にあるクラスの1つ:

<?xml version = "1.0" encoding = "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 = "identity" />
    </ 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-マッピング>

クラスCRResidenceRegionの実装:

[シリアル化可能]
    public class CRResidence:BussinesEntityComponentBase //これは、Equalsを実装し、Id、VersionId、IsDeletedを定義するクラスです。
    {{
    文字列名;
        文字列の郵便番号;
    CRResidenceRegionリージョン;
    TOResidenceCountry国;

    #regionゲッター/セッター

    ///
    ///ナゼフミスタ
    ///
    パブリック文字列名前
    {{
      get {return this.name; }
      set {this.name = value; }
    }
    ///
    /// 領域
    ///
    パブリックCRResidenceRegionリージョン
    {{
      得る
      {{
        this.regionを返します。
      }
      セットする
      {{
        this.region=値;
      }
    }
    ///
    ///Stát
    ///
    パブリックTOResidenceCountry国
    {{
      得る
      {{
        this.countryを返します。
      }
      セットする
      {{
        this.country = value;
      }
    }
    ///
    /// PSC
    ///
    パブリック文字列郵便番号
    {{
      get {return this.postcode; }
      set {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
    ///
    public CRResidence()
      : ベース()
    {{
    }    
}

すべてのタイプのカスケードを試しましたが、どのカスケードも正しく機能しません。しかし、私の機会では、cascade="none"を好みます。クライアント側があり、1つのNHibernateセッションでサーバー側のメソッドを呼び出してオブジェクトCRResidenceRegionをロードします。ロード後、NHibernateセッションは閉じられます。クライアント上のオブジェクトが正しい、データベースからのIDが正しいなど。次に、CRResidenceオブジェクトにCRResidenceRegionオブジェクトが割り当てられます。次に、サーバー側でメソッドと呼ばれます。

using(PersistenceSession session = Registrator.OpenSession())
{{
        ITransaction trx = session.BeginTransaction();
        試す
        {{          
          session.Update(residence);
          //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が更新されました。");
          帰国;
        }
        キャッチ(例外例)
...........。
      }

私はこのようなオブジェクトをたくさん持っていますが、この問題はNHibernate2.1.2に移行したときに発生しました。カスケードスタイルを定義した後、正常に機能する場合もあります(必要に応じて、「すべて」と同様に「なし」が機能しました)。NHibernateの設定ファイルに問題がある可能性があります。

問題の以前の定義:CRResidenceのインスタンスを挿入または更新しようとすると、未保存の一時エラーに関するエラーが発生します。CRResidenceRegionのインスタンスはIdを含めて完全に初期化されているため、問題はありません。IdにEqualメソッドを実装しました。キャッシュをクリアしようとしましたが、役に立ちませんでした。カスケードをsave-updateに変更すると機能しますが、CRResidenceRegionのレコードが複製されます。1つの解決策は、CRResidenceを保存する前に、同じセッションでデータベースからCRResidenceRegionを読み取ることです(以下のコードでコメントされています)が、これは受け入れられません。

NHibernateはCRResidenceRegionへの参照を適切に失い、新しく作成されたと考えているようですが、そうではありません。

4

3 に答える 3

1

Getの代わりにSession.Loadメソッドを使用して、CRResidenceRegionエンティティを初期化します。そのプロパティのいずれかにアクセスしない限り、これは実際にはデータベースに移動しません。

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

これは、別のエッションから来たためかもしれません。

session.Merge()代わりに試してください。

于 2011-06-13T12:24:44.640 に答える
0

私は自分の問題の解決策を見つけました。version_idに問題があり、CR_ResidenceRegionのマッピングファイルに未保存の値を追加しました。

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

unsaved-valueのデフォルト値を変更したと思います。

みんな助けてくれてありがとう

于 2011-06-17T11:55:59.217 に答える