我正在使用Grails 2.3.8。我想添加两个审计字段(createdBy和lastUpdatedBy)到一些域。因此,从audit plugin开始,我创建了一个自定义侦听器。Grails - 创建一个自定义的PersistenceEventListener
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)
}
.
.
.
}
,并对其进行注册内插件:
def doWithApplicationContext = { applicationContext ->
application.mainContext.eventTriggeringInterceptor.datastores.each { key, datastore ->
com.nimbus.NimbusStampListener listener = new com.nimbus.NimbusStampListener(datastore, application)
applicationContext.addApplicationListener(listener)
}
}
监听器被注册成功,同时也听取持久性事件。问题是,当我试图取对象的entity
或entityAccess
字段时,它们为空。
但我可以取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
。
如果有人可以帮助我如何使我的自定义侦听器或点中的实体和实体访问可用,我可以在哪里找到AutoTimestampEventListener
正在注册。我无法在发行版附带的Grails源代码中找到它。
什么是你'beforeInsert'和'beforeUpdate'方法里面做什么? –
我会根据事件类型更新createdBy和lastUpdatedBy字段 –