3

我正在尝试添加自定义 GORM 事件侦听器类Bootstrap.groovy,如Grails 文档中所述,但它不适用于我。这是直接来自文档的代码:

def init = {
    application.mainContext.eventTriggeringInterceptor.datastores.each { k, datastore ->
        applicationContext.addApplicationListener new MyPersistenceListener(datastore)
    }
}

当我运行它时,编译器抱怨 application 和 applicationContext 为空。我尝试将它们添加为类级别成员,但它们并没有神奇地连接到服务风格。到目前为止,我最接近的是:

def grailsApplication
def init = { servletContext ->
    def applicationContext = servletContext.getAttribute(ApplicationAttributes.APPLICATION_CONTEXT)
    grailsApplication.mainContext.eventTriggeringInterceptor.datastores.each { k, datastore ->
        applicationContext.addApplicationListener new GormEventListener(datastore)
    }
}

但我仍然收到错误:java.lang.NullPointerException: Cannot get property 'datastores' on null object.

谢谢阅读...

编辑:版本 2.2.1

4

3 回答 3

8

如果你这样做:

ctx.getBeansOfType(Datastore).values().each { Datastore d ->
   ctx.addApplicationListener new MyPersistenceListener(d)
}

这应该可以在不需要安装 Hibernate 插件的情况下工作

于 2013-07-29T11:29:16.947 回答
5

看起来它应该可以工作,尽管我会做一些不同的事情。BootStrap.groovy 确实支持依赖注入,所以可以注入grailsApplicationbean,但也可以eventTriggeringInterceptor直接注入:

class BootStrap {

   def grailsApplication
   def eventTriggeringInterceptor

   def init = { servletContext ->
      def ctx = grailsApplication.mainContext
      eventTriggeringInterceptor.datastores.values().each { datastore ->
         ctx.addApplicationListener new MyPersistenceListener(datastore)
      }
   }
}

在这里我仍然注入grailsApplication,但只是因为我需要访问ApplicationContext来注册侦听器。这是我的听众(比文档声称最简单的实现更简单;)

import org.grails.datastore.mapping.core.Datastore
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener

class MyPersistenceListener extends AbstractPersistenceEventListener {

   MyPersistenceListener(Datastore datastore) {
      super(datastore)
   }

   protected void onPersistenceEvent(AbstractPersistenceEvent event) {
      println "Event $event.eventType $event.entityObject"
   }

   boolean supportsEventType(Class eventType) { true }
}
于 2013-07-28T23:55:08.100 回答
1

终于偶然发现了一个工作Bootstrap.groovy,感谢这篇文章,但我认为这不是最好的方法,而是一种解决方法。

def init = { servletContext ->
    def applicationContext = servletContext.getAttribute(ApplicationAttributes.APPLICATION_CONTEXT)
    applicationContext.addApplicationListener new GormEventListener(applicationContext.mongoDatastore)
}

所以基本上我直接对 MongoDB 数据存储进行硬编码,而不是像文档建议的那样迭代可用的数据存储。

为了节省您阅读对第一个答案的评论,我在问题中提供的改编版本(以及 Burt 的答案)仅在安装了Hibernate 插件时才有效,但在我的情况下,我使用的是MongoDB 插件,因此不需要Hibernate 插件(实际上它以其他方式破坏了我的应用程序)。

于 2013-07-29T01:31:46.033 回答