Grails and existing Java Hibernate DAO’s

If you have some existing Java Hibernate entity classes (outside Grails), you only have to add one line in Datasource config, and you can use them immediately. However, if you have some exising POJO (Plain Old Java Object) Hibernate DAO’s (classes that implement a Data Access Object pattern), you’ll have to do some additional steps to make it a bit suitable.

(The solution described in this post can also be handy when you need data access on places where GORM is NOT available. GORM not available? Yes, GORM is not fully available when you access collections via a taglib that is accessed via a Sitemesh layout. (A scenerio that isn’t rare.) (Should be considered as a bug?) In that case you will get a lazily initialize a collection error. If you use HibernateUtil, you can get around this by just opening new session yourself.)

Existing Hibernate entities and GORM

You can use existing Hibernate Java entities directly in Grails. The only thing that you’ll have to configure is:

  1. define mappings in hibernate.cfg.xml
  2. set GrailsAnnotationConfiguration as configClass in DataSource.groovy

For example:
webapp/grails-app/conf/hibernate/hibernate.cfg.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <mapping class="myPackage.Product"/>
        <mapping class="myPackage.Customer"/>
        <mapping class="myPackage.Supplier"/>
    </session-factory>
</hibernate-configuration>

webapp/grails-app/conf/DataSource.groovy :

import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration

dataSource {
    configClass = GrailsAnnotationConfiguration.class
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://localhost/mydb"
    username = "myusername"
    password = "mypass"
    dbCreate = "create" // one of 'create', 'create-drop','update'
    dialect= org.hibernate.dialect.MySQLInnoDBDialect
}
hibernate {
    cache.use_second_level_cache=true
    cache.use_query_cache=true
    cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'
}

Now you can put your existing Hibernate java entities in webapp/src/entities (or any other package), and they will work immediately and have GORM functionality.
For example, in the Grails controller classes, you can direcly use Product.get(100) (to get a Product instance that has id 100). Hibernate sessions and transactions are created/invoked automatically.

Exising Hibernate DAO’s

If you don’t need any GORM functionality and you don’t want Grails to touch sessions, then you can use your existing unaltered full hibernate.cfg.xml.

However, if you have some POJO DAO’s that use the HibernateUtil helperclass, you will have to do some additional steps to make it a bit suitable. (In this example, I use the configurations above.)

By default Grails injects a SessionFactory
First, your DAO’s will need a HibernateSession to perform work. By default Grails injects a SessionFactory into Grails controllers that have a “sessionFactory” variable defined. So the following controller will automatically have a SessionFactory available:

import org.hibernate.*;

class ProductController {
    // This one will be injected
    SessionFactory sessionFactory

    def index = {
        Session session = sessionFactory.getCurrentSession()
        println session.createQuery("from Product").list()
    }
}

(You can also use Gorm in this controller example and don’t use the SessionFactory yourself, but this just to show that a SessionFactory will be injected.)

HibernateUtil used by the DAO’s
In the example, the DAO’s use HibernateUtil to get a SessionFactory. By default HibernateUtil create a SessionFactory itself, but the SessionFactory provided by Grails is needed instead, so we alter HibernateUtil slightly:

package persistence;

import org.hibernate.*;

public class HibernateUtil {
    private static SessionFactory sessionFactory;

    public static SessionFactory getSessionFactory() { return sessionFactory; }
    public static void setSessionFactory(SessionFactory sf) { sessionFactory = sf; }

    public static void shutdown() { sessionFactory.close(); }	
}

Set SessionFactory for HibernateUtil
We want HibernatUtil to be ready with a SessionFactory after booting, so we configure HibernateUtil during the bootstap. We alter webapp/grails-app/conf/BootStrap.groovy to:

import persistence.HibernateUtil
import org.springframework.web.context.support.WebApplicationContextUtils

class BootStrap {

     def init = { servletContext ->
        def ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
        def sf  = ctx.getBean('sessionFactory')
        HibernateUtil.setSessionFactory(sf)
     }

     def destroy = {
         HibernateUtil.shutdown()
     }
}

Now the DAO’s can use HibernateUtil.getSessionFactory().getCurrentSession() to get a HibernateSession.

1 thought on “Grails and existing Java Hibernate DAO’s”

  1. I have same entity class mapped as Hibernate DAO and also as a GORM domain object. But controller is using Hibernate DAO rather than a GORM mapped Domain obj.. Any Idea on how to make controllers to only look at GORM managed domain objects ?

Leave a Reply

Your email address will not be published. Required fields are marked *