トランザクションが中止された場合、トランザクション中に保存されたエンティティの識別子を NHibernate にロールバックさせたいと考えています。私は NHibernate 2.1.0 を使用していますが、デフォルトではこれを行いません。私は次の解決策を思いつきました。これはある程度まで機能します。
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 が明示的に呼び出されたエンティティに対してのみ呼び出されます。
カスケード時にも機能させる方法について何か提案はありますか?