2010-12-08 1 views
8

私は、当社の生産のWebサーバー上で次のエラーを取得しています:良いではありませんNHibernate LazyInitializationException ..どのように防止するには?

NHibernate.LazyInitializationException 
: 
Initializing[Domain.Entities.AudienceTypes.Region#4]-failed to lazily initialize a 
collection of role: Domain.Entities.AudienceTypes.Region.PeerGroups, 
no session or session was closed 

を。アプリケーションを再び動作させる唯一の方法は、実際にはオプションではないIISをリセットすることです。これは何を意味するのでしょうか?どうすればそれを防ぐことができますか?

答えて

9

リレーションシップはデフォルトでは遅延です。つまり、リレーションシップをロードするSQLクエリは、リレーションシップを保持するプロパティにアクセスする場合にのみ実行されます。

問題は、以前に呼び出されたことのないレイジープロパティにアクセスした場合、セッションが閉じられたときにエラーが発生することです。 あなたは解決策を持っている:あなたは、セッションへのアクセスに後で使用されるすべての怠惰なプロパティを閉じ前

  • を終了するまで

    • セッションを閉じないでください。
  • 2

    オブジェクトの操作が終了するまで、セッションを終了しないでください。

    これは、NHIbernate IMHOを使用する際の最大の課題の1つです。セッション境界を定義することです。

    ASP.NETアプリケーションでは、セッションはリクエストの開始時に開始され、リクエストの最後にセッションを閉じることができます。

    WinFormsアプリケーションでは、もう少し難しいので、セッションの開始時とセッション終了時の境界を明確に定義する必要があります。 WinFormsアプリケーションでは、通常、ある種類の作業単位を表す「タスク」を定義します。各タスクにはセッションがあります。セッションは、タスクが作成されたときに作成/開かれ、タスクが終了したときに閉じられます。

    次に、いくつかの関連付けをnon-lazyとして定義することもできます。ただし、これを行うとパフォーマンスに影響がないことを確認する必要があります。

    0

    フレデリックとlujopの回答に加えて、あなたがASP.NETアプリケーションを使っているなら(Webサーバーの言及によって示唆されているように)、依存性注入フレームワーク(Castle Windorなど)を使ってISessionのライフサイクルを処理します。キャッスルウィンザーには、これを行う「PerWebRequest」のライフスタイル設定があります。

    失敗した場合、リクエストの最後に破棄される(おそらく自動的に自身をフラッシュする)各リクエストの開始時に手動でISessionを作成します。その後、あなたのアプリはこのセッションを使用できます。

    これは間違いなく、あなたが考える前に閉じているセッションと関係がある。 Fetch.Join()を追加

     
    References(x => x.PeerGroupId, "PeerGroupId").Fetch.Join(); 
    

    以下のように、あなたの地域のマッピングクラスのPeerGroupsのための参照を変更する必要があり、この問題を回避するために

    8

    はLazyInitializationExceptionを防ぐことができます。

    +0

    これは実際の回答です。 – Alex

    関連する問題