1

別のセッションですでに永続化されているが、セッションが閉じられた後もメモリ内で変更されていないエンティティを参照する適切な方法は何ですか?

NHが単一のセッションでエンティティを永続化し、そのセッションが閉じられたら、他の一時的なエンティティで参照するために、新しいセッションでエンティティを再度フェッチする必要があります。または、新しいセッションインスタンスを呼び出しSession.Lockて、このエンティティが一時的ではないことをNHに通知することもできます。このアイテムは、アプリの存続期間中は変更しないでください。

使用するための好ましい方法は何でしょうか?それを行う他の方法はありますか?

[編集]

追加の問題は、ビジネスレイヤーでNHを直接使用しておらず、リポジトリパターンを使用していることです。これは、Session.Lockへのこの呼び出しを抽象化する方法も必要であることを意味します。つまり、リポジトリインターフェイスにSession.Lockと同様のメソッドがあります。これは少し臭い私見です。

4

2 に答える 2

3

最善のアプローチは、第2レベルのキャッシュを有効にして、オブジェクトをキャッシュに適格にすることです。これを行うと、リポジトリメソッドでフェッチできますが、データベースではなくキャッシュからフェッチされます。

于 2010-11-06T23:45:24.993 に答える
2

最初の質問について。エンティティを読むだけの場合は、何もする必要はありません。別のエンティティにフィールドとして割り当てる場合でも、レコードをロックする必要はありません。呼び出す必要がある唯一の理由ISession.Lockは、エンティティを変更して保存する場合です。

例外があり、それは遅延読み込みです。最初のセッションがアクティブなときにロードされなかった外部の子レコードがエンティティにある場合、後でそれらにアクセスしようとすると例外がスローされます。回避する最も簡単な方法は、最初のセッションで子コレクションに触れることです。

このような状況でもエンティティから問題が発生する場合はLoad、リポジトリにを追加できます。これをに配線できますISession.Load。データベースにアクセスLoadせずに、エンティティの空のプロキシを作成します。このエンティティは、エンティティがロードされるセッションの一部であり、他のエンティティのプロパティに割り当てるために使用できます。このアプローチの利点は、非常にクリーンであり、単体テストで簡単にモックできることです。

2番目の質問について。ISession.Lockはい、リポジトリに統合するのは臭いです。繰り返しますが、エンティティを変更する必要がない場合は、これについて心配する必要はありません。しかし、そうだとすれば、リポジトリからエンティティを再ロードすることを考えて、そのエンティティで作業する必要があります。最適ではないことはわかっていますが、特に単体テストでは、非常に奇妙なコードを大幅に節約できます。

最後に一つだけ。長期間存続するエンティティ(おそらくアプリケーションの完全なランタイム)について話しているとのことですが。ライフタイムには、おおよそ3つのカテゴリがあります。1。永遠、2。長い、3。短い。私がこれに言及する理由は、「長い」存続期間を持つエンティティの問題は、実際には同じ存続期間を持つセッションに接続されたままになる可能性があるためです。たとえば、5分または10分(ユーザーがフォームにデータを入力している時間)の間、セッションを存続させても問題ありません。これだけでほとんどの人が多くのトラブルを救うでしょう。

もう1つの注意:とを見てNHibernateUtilくださいNHibernateProxyHelper。これらのクラスは、エンティティと子コレクションのロードを強制するのに役立ちます。

于 2010-11-06T20:08:14.080 に答える