作業単位の開始時にセッションを開始し、作業単位の最後に閉じます。作業単位は、複数の方法にまたがっています。NHibernate:セッションキャッシュからエンティティインスタンスを取得するには?
1つの方法では、Get
メソッドを使用してエンティティをロードします。これはセッションキャッシュに置かれます。エンティティインスタンスはメソッドに対してローカルです。したがって、メソッドスコープが終了すると、エンティティインスタンスにアクセスできなくなります。しかし、エンティティはまだセッションキャッシュにあります。
ここで2番目の方法は、エンティティの新しいインスタンスを作成し、それを削除しようとします。これにより、期待どおりNonUniqueObjectException
がスローされます。
後、私は想像することができるソリューションですが、実装することができません:私は何とかセッションキャッシュからエンティティインスタンスを取得することができる場合、私はそれをEvict
ことができ、うまくいけば、問題が解決されます
public void Delete<T>(T instance) where T : BaseEntity
{
try
{
nhSession.Delete(instance);
}
catch(NonUniqueObjectException)
{
T instanceFromCache = GetInstanceFromCache<T>(instance);
nhSession.Evict(instanceFromCache);
nhSession.Delete(instance);
}
}
。しかし、私は想像上のGetInstanceFromCache
メソッドを実装することができません。
私はnhSession.Get
を使ってみましたが、それは私のシナリオでは役に立たないです。私のデータベースの主キー列名は "id"ではなく、テーブル間で同じではありません。 1つの表では、それは「Field1」であり、他の表では「Field2」である。だから私はnhSession.Get(instance.Id)
のようなものを使うことはできません。私のDelete<T>(T instance)
メソッドは、削除するエンティティインスタンスをパラメータとして受け取ります。削除する主キーの値は受け取りません。
詳細については、私のotherの質問を参照してください。この質問では、UPDATEの問題とその修正方法について説明します。シナリオも同様です。 「@Ricardoペレス」によって
編集1
回答はそのまま動作しませんが、私は彼のコードを少し変更しました。
public static TEntity GetInstanceFromCache<TEntity>(this ISession nhSession, object instance) where TEntity : BaseEntity
{
var sessionImpl = nhSession.GetSessionImplementation();
foreach(BaseEntity baseEntity in sessionImpl.PersistenceContext.EntityEntries.Keys)
{
if(baseEntity is TEntity)
{
TEntity instanceFromCache = (TEntity)baseEntity;
if(nhSession.GetIdentifier(instanceFromCache) == nhSession.GetIdentifier(instance))
return baseEntity as TEntity;
}
}
return null;
}
コールnhSession.GetIdentifier(instance)
が予想される(「インスタンスがこのセッションに関連していなかった」)例外TransientObjectException
をスロー。これはnhSession
にはinstance
が不明であるためです。セッションに関連付けられていないエンティティの識別子を取得する方法はありますか?あなたがのPersistenceContextのホールドを取得する必要があり
プロキシの場合:http://stackoverflow.com/a/10328489/1486443 – Najera