save()and have the framework tackle all the bits and pieces regarding low-level Hibernate usage for me.
From time to time however it is important to have a high-level understanding of what's going on behind the scenes. One example of that is saving entities in services utilized as part of Camel routes. But let's start from the beginning...
In Grails opening Hibernate session is handled by a Spring class called
OpenSessionInViewFilter. This is a filter that opens a Hibernate session before anything else is happening and closes it after the processing is done. With this filter in place a Hibernate session is available throughout the whole request cycle.
When doing processing in Camel we're in a separate thread completely outside the normal Grails request processing so there's nothing there to open the Hibernate session for us. As a side note one needs to remember that the same happens in pretty much every case where a separate thread is fired to do some processing. In all those cases Hibernate session is not available.
But I still want to use GORM in those places! How can I open a session manually?
Well, that's the easiest thing ever. GORM-managed entities expose a method called
withNewSessionthat takes a closure with one parameter (the newly created session) and life is good again.
To make this more common I'll give you two other examples of such a method:
withSession. The first one fires of a new transaction and closes it after the processing is done and the second one is kind of a utility that allows you to access the currently active Hibernate session if you find yourself in need doing so.
I hope this will save someone some time :)