Why you should avoid using autowiring for Grails Domain Classes?

09 May 2017

Tags: Grails, GORM

You should not inject services into a domain class. Why? Autowiring a service into a domain class can have a big performance impact.

Imagine you query 1000 records from a database, and those records are mapped into a GORM entities. Injecting a service into each of those 1000 GORM entities will have a performance cost.

Thus, starting with Grails 3.2.8 auto wiring of GORM entities is disabled when you create an app from scratch. In Grails 3.3.0 or above it is disabled by default.

Let me illustrate this with an example.

The following code will not get the service greetingService injected into a domain class unless you enable auto wiring.

package demo

class Greeter {

    def greetingService

    String name

    String sayHello() {
        "${name}${greetingService.sayHi()}"
    }
}
package demo

class GreetingService {
    String sayHi() {
        'Hello'
    }
}

package demo

class HelloController {

    def index() {
        def person = new Greeter(name: 'Sergio')

        render person.sayHello()
    }
}

If you are autowiring services into your domain instances as in the above example, you will need to re-enable it.

For versions of Grails 3.3.0 or above, you can turn on autowire on a single domain class:

grails-app/domain/demo/Book.groovy

----
class Book {
    BookService bookService

    String name

   static mapping {
       autowire true
   }
   ...
   ..
   .
}

You can turn on autowire for all your domain classes using the http://gorm.grails.org/latest/hibernate/manual/index.html#_the_default_mapping_constraints[Default Mapping] setting:

grails-app/conf/application.groovy

----
grails.gorm.default.mapping = {
        autowire true
}

For versions below Grails 3.3.0, you can re-enable it changing the grails.gorm.autowire configuration parameter.

grails-app/conf/application.yml

----
grails:
    gorm:
        autowire: true

if Spring autowiring of domain instances is enabled, read performance will degrade.

Try to avoid the injection of services in domain classes. Grails has an excellent services layer. You should place your business logic there.

Published on 09 May 2017