2009-08-13 21 views
1

NHibernateの最新ビルドにイベントリスナーを実装して、誰が編集を行っているのか、その編集内容を把握することにしました。私の質問はこれです - 以下はうまくいく、私はそれを踏むことができますが、私はこれらの変更がどのように保存されるのか分かりません...私は監査テーブルを作成し、メソッドは、「更新日時」および「更新日時」情報に沿ってオブジェクトの状態を取得するのが最善です。そのため、後で誰かのためにこれを呼び出すことができます。NHibernateイベントリスナー永続性 - どのように機能しますか?

私は基本クラスがこれ(またはこの機能のサブセット)を提供していると思っていましたが、私がここで欠けているものに関する良いブログ投稿を見つけることができないようです。どんな助けでも大歓迎です!

Imports NHibernate.Event 
Imports NHibernate.Event.Default 

Public Class CustomSaveEventListener 
    Inherits DefaultSaveEventListener 

    Protected Overloads Overrides Function PerformSaveOrUpdate(ByVal evt As SaveOrUpdateEvent) As Object 
     Dim entity As IEntity = TryCast(evt.Entity, IEntity) 
     If entity IsNot Nothing Then 
      ProcessEntityBeforeInsert(entity) 
     End If 

     Return MyBase.PerformSaveOrUpdate(evt) 
    End Function 

    Friend Overridable Sub ProcessEntityBeforeInsert(ByVal entity As IEntity) 
     Dim user As User = DirectCast(Thread.CurrentPrincipal, User) 
     entity.ModifiedBy = user.UserName 
     entity.ModifiedDate = DateTime.Now 
    End Sub 
End Class 

私はリフレクターを開くと、私はこの基本クラスのメソッドは下記を参照してください - しかし、それは正確に何をしているのですか?

protected override object PerformSaveOrUpdate(SaveOrUpdateEvent @event) 
{ 
    EntityEntry entry = @event.Session.PersistenceContext.GetEntry(@event.Entity); 
    if ((entry != null) && (entry.Status != Status.Deleted)) 
    { 
     return this.EntityIsPersistent(@event); 
    } 
    return this.EntityIsTransient(@event); 
} 

答えて

3

エンティティが永続化(保存またはロード)されると、NHはそれを内部辞書(session.PersistenceContext内)に追加します。この辞書のキーはEntityEntryです。EntityEntryには、エンティティの状態(と私が推測する他のもの)に関する情報が含まれています。エンティティが保存されていない(一時的な)場合は、内部ディクショナリにEntityKeyが見つかりません。

それを読み取ることによって、この機能は、エンティティが一時的またはではない、との良好な機能(私はEntityIsTransientの振る舞いを保存するトリガと思い、EntityIsPersitentが更新動作をトリガー)を呼び出し、それを見えるように、それが見えます。

EntityEntry entry = @event.Session.PersistenceContext.GetEntry(@event.Entity); 
    if ((entry != null) && (entry.Status != Status.Deleted)) 
    { 
     return this.EntityIsPersistent(@event); 
    } 
    return this.EntityIsTransient(@event); 

しかし、あなたの問題については、ログシステムのように見えます。 ISaveOrUpdateEventを実装してlog4netを使用して編集内容をログに記録するのはなぜですか?

+0

Session.PersistenceContextの詳細をありがとう - 私は実際には、システムの "履歴"動作を維持しようとしていますが、ストアドプロシージャを使用して保存時に履歴を挿入する代わりに、NHibernate私のためにこれをする。 SQLサーバーの履歴テーブルのマッピングファイルを作成し、このクラスの更新プログラムを呼び出すために、このようなものを維持する唯一の方法はありますか? (保存または更新イベントの直後) –

+0

ようこそ。 詳細は第2の質問には答えられません。私はあなたの考えを良く感じません。保存または更新イベントをインターセプトすると、NHはすでにデータベースアクセスおよびバッチ処理中です。私は一度それが何かを壊すの恐怖によって、フラッシングを開始したNHの動作を変更しないようにしてください。 すべての変更をスタックし、セッションがフラッシュされた後、ログクラスのセーブをやり直すか、プログラムの実行終了時にNHの専用ソリューションが表示されます。 – Nelson

+0

nhセッション(接続の切断など)で例外が発生した場合、それは事態をさらに複雑にします。 これが私がlog4net(http://logging.apache.org/log4net/index.html)について話した理由です。データベースや他のものにログを書き込むように指定することができます(アペンダを探す)。 log4netの設定は初めから分かりにくいですが、これが必要なツールだと思います。 – Nelson

関連する問題