Grails-创建自定义PersistenceEventListener

Grails-创建自定义PersistenceEventListener,grails,Grails,我正在使用Grails2.3.8。我想在一些域中添加两个审计字段(createdBy和lastUpdatedBy)。因此,我从中吸取了这个想法,创建了一个自定义侦听器 package com.nimbus.listener import groovy.util.logging.Log4j import org.grails.datastore.mapping.core.Datastore import org.grails.datastore.mapping.engine.event.Abst

我正在使用Grails2.3.8。我想在一些域中添加两个审计字段(createdBy和lastUpdatedBy)。因此,我从中吸取了这个想法,创建了一个自定义侦听器

package com.nimbus.listener

import groovy.util.logging.Log4j
import org.grails.datastore.mapping.core.Datastore
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
import org.grails.datastore.mapping.engine.event.PreInsertEvent
import org.grails.datastore.mapping.engine.event.PreUpdateEvent
import org.springframework.context.ApplicationEvent

@Log4j
class NimbusStampListener extends AbstractPersistenceEventListener {

    public NimbusStampListener(final Datastore datastore) {
        super(datastore)
    }

    @Override
    protected void onPersistenceEvent(final AbstractPersistenceEvent event) {
        if (event.source != this.datastore) {
            log.trace("Event received for other datastore. Ignoring event")
            return
        }

        if (event instanceof PreInsertEvent) {
            beforeInsert(event.getEntity(), event.getEntityAccess())
        } else if (event instanceof PreUpdateEvent) {
            beforeUpdate(event.getEntity(), event.getEntityAccess())
        }
    }

    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return PreInsertEvent.class.isAssignableFrom(eventType) ||
                PreUpdateEvent.class.isAssignableFrom(eventType)
    }

    .
    .
    .
}
侦听器正在成功注册,并且它还侦听持久性事件。问题是,当我试图获取
事件
对象上的
实体
实体访问
字段时,它们是空的

但是我可以获取
event.entityObject
字段,我可以使用它。但有时在创建新的可审核对象时,createdBy和lastUpdatedBy的值不会在插入时设置,而是会触发一个新的更新事件,该事件会修改对象版本,从而导致项目的其他部分出现
StaleObjectStateException

AbstractPersistenceEvent
类有两个构造函数

protected AbstractPersistenceEvent(final Datastore source, final PersistentEntity entity,
        final EntityAccess entityAccess) {
    super(source);
    this.entity = entity;
    this.entityAccess = entityAccess;
    this.entityObject = entityAccess.getEntity();
}

protected AbstractPersistenceEvent(final Datastore source, final Object entity) {
    super(source);
    entityObject = entity;
    this.entity = null;
    this.entityAccess = null;
}
所以很明显,我的侦听器接收从第二个构造函数创建的事件对象。Grails还有一些内置的监听器,如
AutoTimestampEventListener
,它自动更新域中的时间戳字段(
dateCreated&lastUpdated
)。此侦听器使用entity和entityAccess对象工作,这意味着它们在那里不为null

当我尝试使用
applicationContext.applicationEventMulticaster.applicationListeners
打印通过applicationContext注册的所有侦听器时,它不包含
AutoTimestampEventListener


如果有人能帮助我如何使entity和entityAccess在我的自定义侦听器中可用,或者告诉我如何注册
AutoTimeStampeEventListener
,那就太好了。我在发行版附带的grails源代码中也找不到它

我找到了一些方法来达到我的要求,并想与其他人分享。我创建了两个博客,描述了对我有用的选项。在这里发布整个博客是没有意义的,所以我只想简单介绍一下选项

  • 选项1:连接到
    GormInstanceApi
    并覆盖其方法,然后在那里实现您的逻辑以更新域字段
  • 选项2:不要直接在持久性侦听器中使用Grails事件,而是从这些事件中获取本机Hibernate事件,从而允许您更新事件的当前状态
  • 更多详细说明的博客链接:


    我找到了一些方法来实现我的要求,并想与其他人分享。我创建了两个博客,描述了对我有用的选项。在这里发布整个博客是没有意义的,所以我只想简单介绍一下选项

  • 选项1:连接到
    GormInstanceApi
    并覆盖其方法,然后在那里实现您的逻辑以更新域字段
  • 选项2:不要直接在持久性侦听器中使用Grails事件,而是从这些事件中获取本机Hibernate事件,从而允许您更新事件的当前状态
  • 更多详细说明的博客链接:


    你在
    beforeensert
    beforeeupdate
    方法中做什么?我将根据事件类型更新那里的createdBy和lastUpdatedBy字段你在
    beforeensert
    beforeUpdate
    方法中做什么?我将根据事件更新那里的createdBy和lastUpdatedBy字段类型
    protected AbstractPersistenceEvent(final Datastore source, final PersistentEntity entity,
            final EntityAccess entityAccess) {
        super(source);
        this.entity = entity;
        this.entityAccess = entityAccess;
        this.entityObject = entityAccess.getEntity();
    }
    
    protected AbstractPersistenceEvent(final Datastore source, final Object entity) {
        super(source);
        entityObject = entity;
        this.entity = null;
        this.entityAccess = null;
    }