2009-05-21 13 views
4

NHibernateインターセプタを使用して、さまざまなエンティティに更新/挿入/削除に関する情報を記録しています。NHibernateインターセプタ監査挿入オブジェクトID

ログに記録される情報には、変更されたエンティティのエンティティタイプと一意のIDが含まれます。ユニークなIdは、NHibernateマッピングファイル内で<generator class="identity">とマークされています。

明白な問題は、エンティティのIDがまだ割り当てられていないIInterceptor.OnSave()を使用して挿入操作をログに記録するときです。

監査情報を記録する前に、挿入されたエンティティのIDを取得するにはどうすればよいですか?

(私はNHibernateのリスナーPostSaveイベントに見てきたが、それらが使用されてSpring.net構成で作業を取得することはできませんので、私はすべての可能であればインターセプターに固執したいと思います)

コード:

// object id parameter is null... 
    public override bool OnSave(object entity, object id, object[] state, 
     string[] propertyNames, IType[] types) 
    {    
     AddAuditItem(entity, INSERT); 
     return false;    
    } 

答えて

8

私はこの問題を、OnSaveの実装中にオブジェクトで設定されたインターセプタクラスに追加することで回避しました。

PostFlush実装では、リストが反復され、各要素が挿入として監査されます。このリスト内のオブジェクトはPostFlush()に保持されており、したがってIDを生成しています。

これはOK動作するようですが、どの潜在的な落とし穴が応答のために:-)

public class AuditInterceptor : EmptyInterceptor 
{  
    // To hold inserted items to be audited after insert has been flushed 
    private IList<object> insertItems = new List<object>(); 

    public override void PostFlush(System.Collections.ICollection entities) 
    {    
     foreach (var entity in insertItems) 
     { 
      AddAuditItem(entity, INSERT); 
     } 
     insertItems.Clear(); 

     base.PostFlush(entities); 
    } 

    public override bool OnSave(object entity, object id, object[] state, 
     string[] propertyNames, IType[] types) 
    {    
     var auditable = entity as IAuditable; 
     if (auditable != null) 
      insertItems.Add(entity); 

     return false;    
    } 
} 
+0

+1私はこの12ヶ月前に見ました! – MPritchard

0

OnFlushDirty方法を試してみてください。..または多分PostFlush

編集:また、あなたのコードを投稿することができますか?あなたはOnSaveのパラメータとしてIDを取得していませんか?

+0

感謝を指摘された場合、私は感謝されると思います。 私はPostFlushを試しましたが、挿入されたばかりのICollectionエンティティパラメータのどの項目をどのように伝えることができますか?これを特定する方法があれば、それはうまくいくでしょう... – TonE

+0

私はそれらのすべてを信じています...そうでないのでしょうか? –

+0

いいえ、コレクションには、データベースから状態が更新されたすべてのオブジェクトが含まれます。 – TonE

関連する問題