2011-06-30 7 views
3

私は多くの一対一の関係(cascade = "all-delete-orphan")とコレクションを持つエンティティを持っています。エンティティ(プロパティとコレクション)がダーティであるかどうかのチェック

このエンティティが汚れている(その1対1リレーションからのコレクションとプロパティ/エンティティを含む)ことを確認したいのですが、それを行う方法はありますか?

私はthisの記事を読んでいますが、必要なものはすべてカバーしていません。何か助けていただければ幸いです。

+0

私はこれを行い、ユーザーがフォームを終了できるかどうか、または保存していない変更を彼に警告する必要があるかどうかを確認したいと考えています – dimirc

答えて

0

あなたがそうのように、NHibernateのリスナーを使用することができます。

public class AuditUpdateListener : IPostUpdateEventListener 
{ 
    private const string _noValueString = "*No Value*"; 

    private static string getStringValueFromStateArray(object[] stateArray, int position) 
    { 
     var value = stateArray[position]; 

     return value == null || value.ToString() == string.Empty 
       ? _noValueString 
       : value.ToString(); 
    } 

    public void OnPostUpdate(PostUpdateEvent @event) 
    { 
     if (@event.Entity is AuditLogEntry) 
     { 
      return; 
     } 

     var entityFullName = @event.Entity.GetType().FullName; 

     if (@event.OldState == null) 
     { 
      throw new ArgumentNullException("No old state available for entity type '" + entityFullName + 
              "'. Make sure you're loading it into Session before modifying and saving it."); 
     } 

     int[] dirtyFieldIndexes = @event.Persister.FindDirty(@event.State, @event.OldState, @event.Entity, @event.Session); 

     ISession session = @event.Session.GetSession(EntityMode.Poco); 

     string entityName = @event.Entity.GetType().Name; 
     string entityId = @event.Id.ToString(); 

     foreach (int dirtyFieldIndex in dirtyFieldIndexes) 
     { 
      //For component types, check: 
      // @event.Persister.PropertyTypes[dirtyFieldIndex] is ComponentType 

      var oldValue = getStringValueFromStateArray(@event.OldState, dirtyFieldIndex); 
      var newValue = getStringValueFromStateArray(@event.State, dirtyFieldIndex); 

      if (oldValue == newValue) 
      { 
       continue; 
      } 

      // Log 
      session.Save(new AuditLogEntry 
           { 
            EntityShortName = entityName, 
            FieldName = @event.Persister.PropertyNames[dirtyFieldIndex], 
            EntityFullName = entityFullName, 
            OldValue = oldValue, 
            NewValue = newValue, 
            Username = Environment.UserName, 
            EntityId = entityId, 
            AuditEntryType = AuditEntryType.PostUpdate 
           }); 
     } 

     session.Flush(); 
    } 
} 
+0

これはフラッシュ中であり、また、私はコレクションを通過するとは思わない。 – dimirc

+0

PreUpdateEventListenerはどうですか?これらは最良の方法です... – rebelliard

1

onFlushDirty(...)方法は、(休止中EmptyInterceptorを拡張する)私は汚いコレクションをチェックするために働きます。ネストされたコレクションを持つ親エンティティはonFlushDirtyに渡されますが、渡されたエンティティがコレクション要素である可能性はありません。一度それを見つけたら、ネストされたコレクションとその親エンティティの両方で機能しました。

public class PropertyChangeInterceptor extends EmptyInterceptor{ 

public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) 

別の方法、onCollectionUpdate(...)も汚いコレクションをキャッチするために使用することができ、それがonFlushDirty(...)後に呼び出されます。

関連する問題