nhibernate iPreupdateEventListenerは2番目のテーブルに挿入されません
質問
私は簡単な監査ロギング機能をプロトタイピングしています。私はミッドサイズのエンティティモデル(〜50エンティティ)を持っています、そして私は約5または6に監査ロギングを実装したいと思います。最終的には挿入&削除にも取り組んでいますが、今のところ私はただ私はただ私はアップデートに焦点を当てています。
問題は、EventListener内からSession.Save(またはSaveOrUpdate)をMy AuditLogテーブルに実行すると、元のオブジェクトは正しく永続化(更新)されますが、auditlogオブジェクトは挿入されません。
依然として使用されるセッションのNhibernate Save Lifeサイクルの中で、Pre
とPost
イベントリスナーの両方が問題であると思います。
//in my ISessionFactory Build method
nHibernateConfiguration.EventListeners.PreUpdateEventListeners =
new IPreUpdateEventListener[]{new AuditLogListener()};
//in my AuditLogListener
public class AuditLogListener : IPreUpdateEventListener
{
public bool OnPreUpdate(PreUpdateEvent @event)
{
string message = //code to look at @event.Entity & build message - this works
if (!string.IsNullOrEmpty(message))
AuditLogHelper.Log(message, @event.Session); //Session is an IEventSource
return false; //Don't veto the change
}
}
//In my helper
public static void Log(string message, IEventSource session)
{
var user = session.QueryOver<User>()
.Where(x => x.Name == "John")
.SingleOrDefault();
//have confirmed a valid user is found
var logItem = new AdministrationAuditLog
{
LogDate = DateTime.Now,
Message = message,
User = user
};
(session as ISession).SaveOrUpdate(logItem);
}
.
最後のメソッドでsession.saveOrupdate()にヒットした場合、エラーは発生しません。例外はスローされません。成功して動くようです。しかし何も起こりません。監査ログエントリはデータベースに表示されません。
このメソッド内で完全に新しいセッションとトランザクションを作成するためにそれを機能させることができた唯一の方法では、コードがリスナーメソッドのうちに戻ってきたので、これは本当に理想的ではありません。 My Main AppのSession.Transaction.commit()で、そのトランザクションが失敗した場合は、常に起こったことがないSomethignの監査テーブルに孤立したログメッセージがあります。
私が間違っているかもしれないどんなポインタですか?
編集
このスレッド内のいくつかのコメントに基づいて、イベントから子セッションを使用してLogItemをSaveOrUpdateにしようとしました。 http://ayende.com/blog/3987/nhibernate-IpreUpDateEventListener-IPReInSertEventListener
var childSession = session.GetSession(EntityMode.Poco);
var logItem = new AdministrationAuditLog
{
LogDate = DateTime.Now,
Message = message,
User = databaseLogin.User
};
childSession.SaveOrUpdate(logItem);
.
DBのログテーブルにまだ何も表示されていません。エラーや例外はありません。
解決
onpreupdateメソッドの子セッション、CurrentSession.getSession(EntityMode.Poco)を作成し、これをログ方式で使用する必要があります。FlushMode設定に応じて、子セッションも同様にフラッシュする必要があるかもしれません。
また、あなたがあなた自身の解決策を展開したいのは、特定の理由ですか?FYI、NHIBERNATE監督は今、かなり成熟図書館です。