2011-06-29 12 views
1

NHibernateの多くのセットとリストからの変更(追加と削除)を検出するにはどうしたらいいですか?NHibernateのコレクションの変更を検出する方法

オブジェクトモデル(監査など)の変更を検出するためにインターセプタを使用していますが、これはオブジェクト内の変更(OnSave/OnFlushDirtyを使用)では有効ですが、コレクションでは機能しません。

コレクションが変更されると、OnCollectionUpdateメソッドが呼び出されますが、コレクションを保持するオブジェクトのキーとコレクションの最新のアイテムのみが受け取ります。

は何が必要なのである:コレクション保持

  1. オブジェクト私は今だけのキーを持っている(あるいは、少なくともタイプ+キーは、キーは私のシステムでは、クラス内でのみ一意です)。

  2. コレクション(私は複数のコレクションを持つクラスを持っている)

  3. 追加された項目と削除項目のリスト(あるいは、現在のトランザクションの前と後の回収量)のリストのプロパティ名。

この情報への任意のやり取りはありますか?

答えて

0

ちょっとややこしいかもしれませんが、カスタムプロキシを作成するのはどうですか?

+0

これは私がどのように役立つのか分かりません。私は通常のオブジェクトのプロパティ、コレクションだけで変更を検出するのに問題はありません - そして、コレクションのAddメソッドとRemoveメソッドはプロキシで呼び出されません(これは遅延ロードされていないオブジェクトでは機能しません) – Nir

+0

@Nir soあなたはcolelctionの変更を傍受することができます... –

+0

たとえば、誰かがpost.Commentsを呼び出すときに、ブログデータモデルを使用するとします。Commentsプロパティを追加するgetterはプロキシで呼び出され、キャプチャすることができますが、これはAdd(私が知っているすべてのforeachループからGetEnumeratorになる可能性があります)と呼ばれていません。追加されたもの – Nir

1

現在、私はこの作業を自分で行っています。私自身は(私も見つけるためにしようとしています)まだ第三の質問を考え出したていないが、これは#1、#2で、あなたの方法であなたを助ける必要があります。

public static void SomeMethod(this ISession session, object entity) 
{    
    //this will give you the information about your entity 
    String className = NHibernateProxyHelper.GuessClass(entity).FullName; 
    ISessionImplementor sessionImpl = session.GetSessionImplementation(); 
    IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className); 

    //at this point you can use the persister object to retrieve the info you need: 

    //this gives you all properties and their values 
    Object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode); 

    //this will return the types: 
    IType[] typeArray = persister.PropertyTypes; 

    //each IType object has a IsCollectionType bool which tells you if it is a collection: 
    bool isCollection = IType[0].IsCollectionType; 
} 
0

これはない NHibernateのコードです(それは、Hibernate、Javaコードである)が、NHibernateはAPIをグーグルすると、それは同様のコードのように見えるあなたにもNHibernateのために始めることができ(Owner性質を持っているPersistentMapクラス、およびCollectionSnapshotプロパティがあります):

public void onCollectionUpdate(Object collection, Serializable id) { 
    System.out.println("****onCollectionUpdate"); 

    if(collection instanceof PersistentMap) { 
     PersistentMap newValues = (PersistentMap) collection; 
     Object owner = newValues != null ? newValues.getOwner() : null; 
     Set<?> oldValues = newValues != null 
      ? ((Map<?, ?>) newValues.getStoredSnapshot()).keySet() 
      : null; 

     System.out.println("owner: " + (owner != null ? owner.toString() : "(null)")); 
     System.out.println("oldValues: " + (oldValues != null ? oldValues.toString() : "(null)")); 
     System.out.println("newValues: " + (newValues != null ? newValues.toString() : "(null)")); 
    } else if (collection instanceof PersistentSet) { 
     PersistentSet newValues = (PersistentSet) collection; 
     Object owner = newValues != null ? newValues.getOwner() : null; 
     Set<?> oldValues = newValues != null 
      ? ((Map<?, ?>) newValues.getStoredSnapshot()).keySet() 
      : null; 

     System.out.println("owner: " + (owner != null ? owner.toString() : "(null)")); 
     System.out.println("oldValues: " + (oldValues != null ? oldValues.toString() : "(null)")); 
     System.out.println("newValues: " + (newValues != null ? newValues.toString() : "(null)")); 
    } 
} 

私はこれがC#またはNHibernateのコードではないことに注意してください。 NHibernateにとってまったく役に立たない場合はコメントしてください(もし私のグーグルがそれが似ていると言っても、APIが全く似ていない場合)、投稿を削除します。

私は今のJava土地に浸漬しています、または私はあなたのためにこれを試してみたい:)

1

あなたはスタンダールNHibernateのコレクション(リスト、セット、マップ)をオーバーライドしない場合、あなたは常に初期取得することができますコレクションの内容(変更前のベースに保存されたコンテンツ)リストの例:

確かに、どの要素が追加、削除、または変更されていないか把握することができます。

+0

スナップショットのコンテンツと実際の永続的なコレクションのコンテンツを単に比較できないのはなぜですか? –

関連する問題