Why You Should Avoid Using Autowiring for Grails® Domain Classes
May 9, 2017
Tags: #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 1,000 records from a database, and those records are mapped into a GORM entities. Injecting a service into each of those 1,000 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 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. the Grails framework has an excellent services layer. You should place your business logic there.