Friday, January 18, 2008

Migrating to Grails?

The last time I looked at Grails it was around version 0.4. Now that we are approaching a 1.0 release I wanted to see how much further the Grails team has advanced. I wanted to start by using my existing Spring and Hibernate components from my Java project (I am currently using Stripes for our presentation layer). Benefits for doing this might include:
  • Abstracting your Java domain model and services so they are not coupled to Grails.

  • The ability to continue using your Java services and model objects outside of Web applications or have the ability to integrate with other Web presentation frameworks.

  • A migration path to Groovy if you want to rid yourself of straight Java altogether. I am sure that there would be massive redux in LOC. For me it was experimenting with the intersection of my experiences with Rails and Java Web development.

Does this mean that if you reuse your Hibernate Java domain objects you do not get all of the GORM features like (order.save())? No, your domain objects transparently take full advantage of the mixed in methods in Grails. You might find that the services you are reusing from Spring are mostly passthroughs to DAO that you do not need anymore because of GORM. Here is a trivial example showing how to use a Grails controller to use existing Spring services to perform DAO operations and how to use your Hibernate domain objects directly as GORM objects:


UserService userService  // This is injected in via auto-wiring

def index = {

// Using Java Services
def user = userService.find(1, User.class)
println user.firstName
user.firstName = 'Mark'
userService.save user
println User.get(1).firstName

// Using strait Grails
user = User.get(1)
println user.firstName
user.firstName = 'Phil'
user.save()
println User.get(1).firstName
}

Here is how we took our annotated Hiberate classes so Grails would recognize them:

Edit your hibernate.cfg.xml file in the GRAILS_APP/grails_app/conf/hibernate directory and add your domain objects:

<!DOCTYPE hibernate-configuration SYSTEM
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="com.meagle.common.bo.Address" />
<mapping class="com.meagle.common.bo.User" />
</session-factory>
</hibernate-configuration>
In your DataSource.groovy configuration file add the configClass line to your datasource configuration so your annotated Hibernate classes will be recognized by Grails:
dataSource {
pooled = false
driverClassName = "com.ibm.db2.jcc.DB2Driver"
username = "meagle"
password = "******"
configClass
=org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration.class
}
Here is how you expose your existing Spring beans to your Grails application:
  1. Edit your GRAILS_APP/grails_app/conf/spring/resources.xml file and add the following line:
    <import resource="applicationContext-core.xml"/>
    This tells Grails to include your Spring resources (We put our Spring config file in the same directory as the resources.xml file).

  2. Make sure all of your Spring and Hibernate domain objects written in Java are on the classpath. We put ours in a jar file in the GRAILS_APP/lib directory.

One gotcha here to remember is that your Spring configuration file should not include any definition to a SessionFactory and your services and DAOs that reference a SessionFactory needs to be the name "sessionFactory". Otherwise, you will end up with multiple session factory objects which is probably not what you want.

Overall I am very impressed with Grails at this point and would challenge Java developers to take a serious look at this framework. If you are fortunate enough to have IntelliJ 7 then there is decent plugin support for building Grails applications.