I use Grails GPaars to create an async block.
In BuildConfig:
compile 'org.codehaus.gpars:gpars:1.2.1'
compile 'org.codehaus.jsr166-mirror:jsr166y:1.7.0'
I defined a helper Class:
class TaskService {
private ForkJoinPool pool = new ForkJoinPool()
/**
* Executes the given closure in a new thread.
* @param args is a map of arguments to be used in the async closure.
* @return
*/
def executeAsync(args, closure = null) {
if(!closure) {
closure = args
args = null
}
GParsPool.withExistingPool(pool) { closure.callAsync(args) }
}
}
Now in a controller I do:
TrackingEmail tEmail = TrackingEmail.get(trackingEmailId)
Device targetDevice = tEmail.device
The former works the device
is retrieved from the TrackingEmail object.
Now I try to do the same in an async block:
taskService.executeAsync(trackingEmailId: trackingEmailId) { data ->
TrackingEmail tEmail = TrackingEmail.get(data.trackingEmailId)
Device targetDevice = tEmail.device
}
In this async block only tEmail
is retrieved from the database. The second line is not executed.
How do I get relational objects in an async block?
I don't think you should use GPars for GORMing directly. In this case you would have to take care of transactions/sessions yourself:
taskService.executeAsync(trackingEmailId: trackingEmailId) { data ->
Device.withTransaction{ tx ->
TrackingEmail tEmail = TrackingEmail.get(data.trackingEmailId)
Device targetDevice = tEmail.device
}
}
and that would give you bad performace in case of frequent parallel calls.
I'd recommend to take a look at Asynchronous Programming in Grails, which uses the extended GPars