多くの質問と回答を読みましたが、問題の解決策を見つけることができませんでした。この問題は、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への参照を適切に失い、新しく作成されたと考えているようですが、そうではありません。