我正在使用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字段 –