Sharepoint ベースの ASP.NET プロジェクトの既存の nHibernate コードを、積極的な読み込みとデータベース ヒットごとの新しいセッションから、遅延読み込みと HTTP 要求の間のセッションに切り替え始めたところ、問題が発生し始めました。
このシステムでアイテムを作成すると、ドロップダウンによって入力される多対 1 の関係がいくつかあります。これで ID が取得され、データベースに保存するのに十分です。
電子メール通知などの保存後のタスクを実行するために、以前はオブジェクト ツリー全体が取り込まれていた同じアイテムを再度読み込みます。
ただし、遅延読み込みとリクエスト全体の有効期間を持つセッションへの変更以来、不可解な null である Item の下のプロパティから NullReferenceExceptions を取得しています。
nHibernate を介して changedItem にアイテムをロードします。失敗している呼び出しは次のとおりです。
changedItem.PaperMedia.FormsAnalyst.User.Contact.Name
PaperMedia は完全に入力されていますが、FormsAnalyst のすべてが ID を除いて null です。
これは保存したときと同じ状態であるため、この問題の考えられる原因の 1 つは、Item がキャッシュされ、単純に取得され、nHibernate がデータベースからの実際の値を認識していないことです。ただし、トランザクションをコミットし、保存と後続のロードの間にセッションで Flush() を明示的に呼び出しているため、その場合、Commit() も Flush() もキャッシュに影響しません。
関連する hbm.xml ファイルのこれらのプロパティを lazy="false" に変更し、それらすべてに SetFetchMode FetchMode.Eager を設定しましたが、効果がありません。
問題として max_fetch_depth も検討していました。セッションで Refresh(changedItem) を呼び出しても効果はありません。ただし、Refresh(changedItem.PaperMedia) を呼び出すと、Name まですべてが読み込まれます。これは問題として max_fetch_depth を軽視しているように見えますが、それでも私は hibernate.cfg.xml で 6 に設定し、構成インスタンスで SetProperty("max_fetch_depth", "6") に設定して、それを増やそうとしました。セッションファクトリの作成中に、これらも効果がありませんでした。
他に何を試すべきかわかりません。
前にそのようなものを見た人はいますか?私はnHibernateを初めて使用するので、簡単なものかもしれません...
編集:
キャッシングが実際に問題であるように思われます。セッション インスタンスで Clear() を呼び出すと、この動作が修正されます。
では、なぜ Flush() はキャッシュされたアイテムを更新しないのでしょうか? それはまさに私がそれを行うために構築されたと思ったことです。