Grails 在域类methode中调用服务methode时发生NullPointerException

Grails 在域类methode中调用服务methode时发生NullPointerException,grails,gorm,Grails,Gorm,根据Grails,应该可以在域类中使用服务。但是,当我运行下面的简单示例时,grails run应用程序失败,出现一个NullPointerException:“无法在null对象上调用方法test()” 要复制,请使用以下代码段: Bootstrap.groovy: class BootStrap { def init = { servletContext -> new Test().test() } def destroy = { } }

根据Grails,应该可以在域类中使用服务。但是,当我运行下面的简单示例时,grails run应用程序失败,出现一个NullPointerException:“无法在null对象上调用方法test()”

要复制,请使用以下代码段:

Bootstrap.groovy:

class BootStrap {
    def init = { servletContext ->
        new Test().test()
    }
    def destroy = {
    }
}
使用该服务:

@Transactional
class TestService {
    def test() {
    }
}
和域类:

class Test {
    def testService

    def test() {
        testService.test()
    }
}
Holders.applicationContext.serviceName.methodName()
Grails3.2.9和3.3.0就是这样。这是Grails错误还是GORM失败,而不是将服务自动注入域类

解决方案: 对于所有想知道使用“静态映射={autowire true}”解决方案是什么的人(参见erichelgeson的答案)。但在测试这两种解决方案时,我发现“静态映射…”在Grails 3.3.0和3.2.9中有效,因此在应用程序中全局设置它。yml只在Grails 3.2.9中有效,但在Grails 3.3.0中无效。

出于性能原因,Grails(3.2.9+)的最新版本默认情况下在域类上禁用了autowire。您可以重新启用它:

每个域:

static mapping = {
   autowire true
}
或在application.yml/groovy中全局使用

grails.gorm.autowire = true
查看更多@
第1.2.9节

您可以根据前面的建议重新启用自动布线,但这会影响整个应用程序的性能。如果这是一种普遍的情况,那么这可能是值得的

如果这对您来说是一种罕见的情况,您也可以访问域类中的服务:

class Test {
    def testService

    def test() {
        testService.test()
    }
}
Holders.applicationContext.serviceName.methodName()

尝试在调用周围包装withTransaction,以便
Test.withTransaction{new Test().Test()}
。但我要对你说实话。这一切似乎都非常落后,因为您正在使用引导调用触发服务的域类。直接在已经是事务性的引导中调用服务,并且使用“Test.withTransaction{..}”进行记录添加没有帮助。我已经试过了。在引导中使用“new Test().Test()”只是一种简单的方法来强制执行此错误,而不需要用户交互。它并不意味着其他任何东西:-)谢谢,在Grails3.3.0和3.2.9中,使用“静态映射={autowire true}”的技巧确实有效。但在application.yml中全局设置它只适用于Grails3.2.9,而不适用于Grails3.3.0。