Monday, July 25, 2011

Grails, Camel and Hibernate session

It's been a while since I thought about manually opening Hibernate sessions to do some work on the database. The usual thing is simply to call one of the GORM methods like get() or 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 withNewSession that 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: withTransaction and 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 :)

Friday, July 22, 2011

Grails and Spring inc.

I just found a very nice article by Peter Ledbrook showing how you can integrate a regular Spring MVC part of your application with Grails. If you need to do any sort of Spring-related stuff in your Grails application I suggest you check it out!

http://blog.springsource.com/2010/06/08/spring-the-foundation-for-grails/

Have a nice day!

Grails, routing plugin and GORM

I's been brought to my attention today that it is possible that Camel routes start sooner than some of the other services in Grails (GORM in particular). This leads to issues like missing methods in domain classes. To get around this problem you can do as follows:

In your route definition add the .noAutoStartup() part like this:
from('direct:foo').routeId('myRoute').noAutoStartup()....
In BootStrap.groovy's init closure add the following code:
import org.codehaus.groovy.grails.web.context.*
[...]
def ctx = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
ctx.camelContext.startRoute('myRoute')
This will give you the possibility to start and even stop a route anytime you want.

You can read more on this topic on fusesource.com.

I hope this will help someone :)

Tuesday, July 19, 2011

Grails routing 1.1.3 released!

I'm happy to announce the immediate availability of the routing and routing-jms plugins. The major theme for this release is hot reloading of Camel inner-workings when service classes are changed.

So.. well... it works. For the most part at least. It wasn't easy but let's examine the changes and new capabilities one step at a time.

Apache Camel.

In Apache Camel there's no obvious way to force the routes to re-get the bean from Spring context. An endpoint caches an instance of BeanProcessor that's created with ConstantBeanInfo instance and that's pretty much it.
Thankfully the BeanProcessor instance is not final and is lazy initialized so if you force it to be null by calling setProcessor(null) the next time the endpoint is called it needs to re-create the processor and all is good. It's a pity no one thought of a "forceReinitialize" method in Camel but this way works too.

Grails.

In Grails it is pretty much standard that you are allowed to overwrite the existing instance of a service class with a new implementation. This mechanism is sort of baked in into the core.
However when reloading services that are marked as transactional there's some AOP going on with cglib and caching that I couldn't quite crack so those kind of services when reloaded will produce an exception that says "SomeService cannot be cast to SomeService" or something of this sort. I'll have to get back to it some day and figure out if this is a general problem with Grails or if it is something I'm missing in my onChange handler. For now if you need your method to participate in transaction you'll have to manually call the withTransaction { } helper.

Bottom line.

The bottom line is that you finally can use the routing plugin to do normal Grails development and it should catch you with no surprise (other than the transactional services...). Go and give it a shot. Let me know if it works for you!

Happy Cameling!

Grails routing plugin - report from the battlefield

Just wanted to let you all know that I've resumed work on improving the routing plugin for Grails. There's already version 1.1.2 that introduces a new method added to controllers, services and (if Quartz plugin is installed) jobs that allows you to send messages with headers.

The next task however isn't simple and will take some time. It's the long standing problem with Camel routes that target beans that are reloaded.

Will see where this will lead me.