2017-08-24 62 views
1

根据Grails,应该可以在域类中使用服务。但是,当我运行下面简单的例子,Grails的运行的应用程序失败,一个NullPointerException:“不能调用方法测试()null对象的”在域类方法中调用服务方法时发生NullPointerException

要重现使用下面的代码片段:

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() 
    } 
} 

这发生在Grails 3.2.9和3.3.0上。这是Grails错误还是GORM失败,而不是自动将服务注入到域类中?

SOLUTION: 对于所有想知道解决方法是什么(请参阅erichelgeson的答案),使用“static mapping = {autowire true}”。但是对这两种解决方案进行测试后,我发现“静态映射......”在Grails 3.3.0和3.2.9中起作用,因此在application.yml中进行了全局设置,它仅适用于Grails 3.2.9,而不适用于Grails 3.3.0你。

+0

尝试包裹呼叫周围withTransaction所以'Test.withTransaction {新的测试() .test()}'。但我会对你说实话。这一切似乎都非常落后,您正在使用引导来调用触发服务的域类。在Bootstrap中直接调用服务,这已经是事务性的,并且添加了记录 – Vahid

+0

使用“Test.withTransaction {..}”没有帮助。我已经试过了。 –

+0

在Bootstrap中使用“new Test()。test()”只是一种简单的方法来强制执行此错误,无需用户交互。它并不意味着什么:-) –

回答

2

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

每个域:

static mapping = { 
    autowire true 
} 

或在全球范围内application.yml /常规

grails.gorm.autowire = true 

查看更多@http://gorm.grails.org/6.1.x/hibernate/manual/index.html 第1.2.9

+1

谢谢,“静态映射= {autowire true}”的技巧在Grails 3.3.0和3.2.9中都有效。但在application.yml中全局设置它只适用于Grails 3.2.9,但不适用于Grails 3.3.0。 –

0

你可以根据先前的建议重新启用自动装配,但是对于您的整个应用程序会有性能影响。这可能是值得的,如果这是常见的情况。

如果这对你是一个罕见的情况,你也可以访问服务,因为这样,在一个领域类:

Holders.applicationContext.serviceName.methodName() 
相关问题