2009-11-04 7 views
1

트랜잭션이 중단되면 트랜잭션 중에 저장된 엔티티의 식별자를 롤백하도록 NHibernate를 얻고 싶습니다. 나는 NHibernate 2.1.0을 사용하고 있으며 기본적으로이 작업을 수행하지 않는다.식별자 롤백 NHibernate

public class RevertIdentifiersEventListener : DefaultSaveEventListener 
{ 
    private class RevertIdentiferSynchronization : ISynchronization 
    { 
     private IClassMetadata _classMetadata; 
     private object _entity; 
     private object _originalIdentifier; 

     public RevertIdentiferSynchronization(IClassMetadata classMetadata, object entity) 
     { 
      _classMetadata = classMetadata; 
      _entity = entity; 
      _originalIdentifier = classMetadata.GetIdentifier(entity, NHibernate.EntityMode.Poco); 
     } 

     #region ISynchronization Members 

     public void AfterCompletion(bool success) 
     { 
      if (success == false) 
      { 
       _classMetadata.SetIdentifier(_entity, _originalIdentifier, NHibernate.EntityMode.Poco); 
      } 
     } 

     public void BeforeCompletion() 
     { 
     } 

     #endregion 
    } 


    protected override object EntityIsTransient(SaveOrUpdateEvent @event) 
    { 
     IEntityPersister entityPersister = @event.Session.GetEntityPersister(@event.EntityName, @event.Entity); 
     if (entityPersister.HasIdentifierProperty) 
     { 
      RevertIdentiferSynchronization revertIdentiferSynchronization = new RevertIdentiferSynchronization(entityPersister.ClassMetadata, @event.Entity); 
      if (@event.Session.Transaction.IsActive) 
      { 
       @event.Session.Transaction.RegisterSynchronization(revertIdentiferSynchronization); 
      } 
     } 
     return base.EntityIsTransient(@event); 
    } 

} 

문제는 엔티티 폭포의 저장은 관련 단체에 저장하면 해당 엔터티의 식별자가 롤백되지 않는 것입니다 : 나는 시점까지 작동하는 다음과 같은 솔루션을 함께했다. 위의 EntityIsTransient는 이러한 엔티티에 대해 호출되지 않으며 Save가 명시 적으로 호출되는 엔티티에 대해서만 호출됩니다.

계단식 연결시 작동시키는 방법에 대한 제안 사항이 있으십니까?

답변

0

나는 당신이 트랜잭션을 중단 할 어떤 상황에서 잘 모르겠지만, 난 당신이 뭔가를해야 할 가정입니다 : 그녀는 당신이 롤백 후 무엇을 묻는 데요

using(var transaction = SessionFactory.GetSession().BeginTransaction()) 
    { 
     try 
     { 
      session.Update(entity); // throws exception for some reason 
     } 
     catch(Exception ex) 
     { 
      transaction.Rollback(); // rollback the transaction 
     } 
    } 
+0

. 나는이 같은 문제를 겪고있다. 엔터티에 새로운 자식 모델에 대한 참조가 포함되어 있고 NHibernate가 그 자식 엔터티를 삽입하려고 시도하면 NHibernate는 더 이상 새로운 Guid()가 아니도록 식별자 (Guid)를 변경합니다. 우리는 자식 객체의 식별자를 어떤 식 으로든 롤백 할 필요가있다. – ctrlShiftBryan