NHibernate 3.2 - Pre 和 Post 删除未调用的事件侦听器

NHibernate 3.2 - Pre and Post Delete event listeners not invoked

我正在针对 NHibernate 3.2 的实现工作,其中包含几个自定义实体状态更改侦听器:PreDelete、Delete 和 PostDelete。 DeleteEventListener 是通过从 DefaultDeleteEventListener 继承自定义类型定义的,但其他的只是实现 IEventListener 接口。

CustomDeleteEventListener 的主体如下:

protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities)
{
    if (entity is BaseEntity)
        HandleEntityAssociations(session, (BaseEntity)entity);

    if (entity is ISoftDeletable) 
    {  
        var e = (ISoftDeletable)entity;
        Utility.SetTrackingInfo(e as BaseModel);

        e.Deleted = true; 

        CascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities); 
        CascadeAfterDelete(session, persister, entity, transientEntities); 
    } 
    else 
    { 
        base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities); 
    } 
}

在我的测试中,我发现 OnDelete() 侦听器总是在 OnPreDelete()OnPostDelete() 侦听器之前被调用 ,并且如果不调用 base.DeleteEntity(),Pre 和 Post 侦听器将永远不会触发。这对我来说没有任何意义——我希望顺序是:OnPreDelete()OnDelete()OnPostDelete()

当我检查调用堆栈时,我注意到 OnDeleteEvent() 是由对 FireDelete() 的基础调用触发的,该调用在对 ISession.Delete() 的调用之后立即调用,但是 OnPreDeleteEvent() 是由 OnFlush() 的侦听器触发 - 完全断开对 OnDeleteEvent().

的调用

几乎没有关于这些侦听器的文档,只有少数博客将它们用于这样那样的用途。有谁知道这些在 NHibernate 3.2 中是如何工作的,以及为什么我会看到我现在的行为?

据我了解,OnDeleteOnUpdate、...用于执行诸如验证之类的操作,或修改正在删除、更新、插入的实际实体。这几乎发生在管道的开始处,参见例如"NHibernate interceptor magic tricks, pt. 4"

When a delete occurres, the very first thing NHibernate does, is calling IInterceptor.OnDelete(object entity, object id, object[] state, string[] propertyNames, IType[] types) method. It does not provide any flow control and is simply called by the default IDeleteEventListener before scheduling the real delete action.

另请参阅该博客系列的其他部分以获取更多信息。

PreDeletePostDelete 事件侦听器在 DeleteAction 中调用,它本身是由 DefaultDeleteEventListener 创建的(即 class 你派生自) 在其 DeleteEntity 方法中,并添加到会话的操作队列中。因此,它们在 DeleteEventListener 调用之后被调用。

Pre... 事件发生在实际命令发出之前。到那时,通过修改实体本身来强制更改命令为时已晚,尽管您可以使用命令的参数(并确保还将这些更改应用于相应实体的字段),或执行其他操作(例如插入审计记录)通过使用子会话。从这些 Pre... 侦听器中的任何一个返回 true 将否决更改,返回 false 将导致执行它。

您可能想阅读此博客 post:NHibernate IPreUpdateEventListener & IPreInsertEventListener。跟update和insert监听器有关系,但是对于delete,道理差不多

Those allow us to execute our custom logic before the update / insert is sent to the database. On the face of it, it seems like a trivial task, but there are some subtleties that we need to consider when we use them.

Those hooks run awfully late in the processing pipeline, that is part of what make them so useful, but because they run so late, when we use them, we have to be aware to what we are doing with them and how it impacts the rest of the application.

看来"awfully late"的意思是:

the ADO.Net Command that will be executed as soon as the event listener finish running.

由于 NHibernate 扎根于 Java Hibernate 版本,它具有相同类型的侦听器和事件,因此这是有关此主题的更多官方文档的另一个潜在信息来源。