7
votes

The Grails FAQ says this:

Q: How can I access domain classes from sources in src/groovy?

Sometimes, you are developing some utility classes that live in src/groovy and which you intend >to use from Services and other artifacts. However, as those classes are pre-compiled by Grails, >it is not possible to instantiate them and write things like Book.findByTitle("Groovy in >Action"). But fortunately, there is a workaround since it's possible to do this:

import org.codehaus.groovy.grails.commons.ApplicationHolder

//…

def book = ApplicationHolder.application.getClassForName("library.Book").findByTitle("Groovy in Action")

The application MUST have finished bootstrapping before the dynamic Gorm methods will function correctly.

However, it appears that I can directly import domain objects and use GORM methods in my src/groovy classes without any problem, e.g.:

Book.findByTitle("Groovy in Action")

Since ApplicationHolder is deprecated, this advice must be out of date, but is there still any reason to avoid using domain classes directly from src/groovy?

1
Older versions of grails implemented auto-reloading of modified artefacts in dev mode by using different class loaders for artefact (grails-app) and non-artefact (src/groovy) classes. More recent grails versions use an agent-based reloading approach instead, and it's all in the one class loader.Ian Roberts

1 Answers

6
votes

You are correct, you referring to an out dated information. You can use domain classes inside classes defined under src/groovy.

The only overhead is that you have to handle transactions manually. On the contrary, services inside grails-app/services handes transaction by default. Services take care of transactions when the transactional flag is set to true (default is true of nothing specified).

On the other hand, when you access domain classes from src/groovy you have to use withTransaction block to handle transactions manually..

Book.withTransaction{status->
    def book = Book.findByTitle("Groovy in Action")
    book.title = "Grails in Action"
    book.save()

    status.setRollbackOnly() //Rolls back the transaction
}

Refer withTransaction for details.