简体   繁体   中英

Why don't Domain class static methods work from inside a grails “service”?

I want a grails service to be able to access Domain static methods, for queries, etc.

For example, in a controller, I can call

IncomingCall.count()

to get the number of records in table "IncomingCall"

but if I try to do this from inside a service, I get the error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'incomingStatusService': Invocation of init method failed; nested exception is groovy.lang.MissingMethodException: No signature of method: static ms.wdw.tropocontrol.IncomingCall.count() is applicable for argument types: () values: []

How do these methods get injected? There's no magic def statement in a controller that appears to do this. Or is the problem that Hibernate isn't available from my Service class?

I also tried it this way:

import ms.wdw.tropocontrol.IncomingCall
import org.codehaus.groovy.grails.commons.ApplicationHolder

// ...

void afterPropertiesSet() {

    def count = ApplicationHolder.application.getClassForName("IncomingCall").count()
    print "Count is " + count
}

and it failed. ApplicationHolder.application.getClassForName("IncomingCall") returned null. Is this just too early to call this? Is there a "late init" that can be called? I thought that was the purpose of "afterPropertiesSet()"...

The metaclass methods are wired up after the Spring application context is configured, so trying to call them in afterPropertiesSet will fail. Instead you can create a regular init() method and call that from BootStrap:

import ms.wdw.tropocontrol.IncomingCall

class FooService {

   void init() {
      int count = IncomingCall.count()
      println "Count is " + count
   }
}

and call that with this:

class BootStrap {

   def fooService

   def init = { servletContext ->
      fooService.init()
   }
}

The real answer, I discovered, is not to do this.

I should instead inject my service into my domain class and call it from there.

I can use the "trigger" methods, like afterInsert to call my service methods as needed

class Deal {
    def authenticateService

    def afterInsert() {
        def user = authenticateService.userDomain();
        ....
    }
....
}

(for example, from the grails services documentation)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM