2009-11-04 41 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會嘗試插入該子實體,從而更改其標識符(Guid),以便它不再是新的Guid()。我們需要以某種方式回滾子對象的標識符,所以我們知道它從來沒有被採用。 – ctrlShiftBryan 2011-12-23 17:53:20