I've been trying to come up with the proper way to cancel a delete operation using the interfaces provided.
In search of a comprehensive answer to this question, I've reviewed the source code for both the main trunk and the 1.2.x branch. In both branches the OnDelete IInterceptor interface contains no return value to cancel the delete operation. In both branches the ILifecycle event can cancel a delete.
The trunk branch and the 1.2.x branch differ slightly in implementation as far as timing is concerned.
Trunk:
Lifecycle Check then IInterceptor.OnDelete
Code:
public void OnDelete(DeleteEvent @event, ISet transientEntities) {
...
if (InvokeDeleteLifecycle(source, entity, persister))
{
return;
}
DeleteEntity(source, entity, entityEntry, @event.CascadeDeleteEnabled, persister, transientEntities);
}
protected internal void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities){
...
session.Interceptor.OnDelete(entity, entityEntry.Id, deletedState, persister.PropertyNames, propTypes);
}
1.2.x Branch:IInterceptor.OnDelete then Lifecycle Check
Code:
private void DoDelete(object obj, EntityEntry entry, IEntityPersister persister){
...
interceptor.OnDelete(obj, entry.Id, entry.DeletedState, persister.PropertyNames, propTypes);
...
if (((ILifecycle) obj).OnDelete(this) == LifecycleVeto.Veto)
{
//rollback deletion
}
}
So either way the IInterceptor.OnDelete can't ever cancel the delete operation.
One potential solution is to use the ILifecycle event. But in reading the migration guide we know that the ILifecycle and IValidatable interfaces have been deprecated.
From the NHibernate 1.2 Migration Guide:
Quote:
ILifecycle and IValidatable interfaces
The ILifecycle and IValidatable interfaces were deprecated in NHibernate 1.2 and moved to the NHibernate.Classic namespace. The Hibernate team does not consider it good practice to have domain
model classes depend upon persistence-specific APIs. NHibernate 1.2 applications should use IInterceptor interface. Existing applications may continue to use ILifecycle and IValidatable.
IInterceptor interface
Several new methods were added to the IInterceptor interface. Existing interceptors will need to be upgraded to provide empty implementations of the two new methods.
To avoid issues with interceptor migration (whether 1.0.x -> 1.2.x, or moving forward), just extend the new EmptyInterceptor class instead of writing your own empty implementation for all methods you don't need.
Solution?
Ahh so there's the solution. We need to add a new event to the IIntereceptor such as BeforeOnDelete that allows us to cancel the deletion. As I need this functionality for my temporal database I'm going to attempt to do this. I would LOVE it if one of the main NHibernate contributors could let me know if I'm on the right track here. I'll hopefully be able to upload a patch to JIRA when it comes back online. (I haven't been able to access JIRA for a few days.)