Using GORM outside of Grails

I’ve seen questions about using GORM outside of Grails in standalone apps but didn’t think much about it – I don’t mind using Hibernate directly. It came up again today on the Grails User mailing list, so I thought I’d take a look.

It turns out that Jeremie Weldin got this working quite a while ago but it no longer works with the latest version of Grails. I’ve been mucking around in the Grails internals trying to get a plugin together that’ll allow multiple datasources in a single app, so I figured it wouldn’t take long to get things going. As usual I was overly optimistic, but several hours later it’s ready to share.


I tried to use the public API and not copy/paste code or call private methods, since I’d like for this to continue working with future versions of Grails. So the main trick here is to call DomainClassGrailsPlugin.doWithDynamicMethods and HibernateGrailsPlugin.doWithDynamicMethods to leverage that functionality. The rest of the app basically just configures the Application, SessionFactory, Configuration, and TransactionManager.

Some notes:

  • It’s set up to support annotated classes via a GrailsAnnotationConfiguration, although I haven’t tested that here. You’d follow the same steps as regular Grails – put the jar in the lib directory and a hibernate.cfg.xml file in grails-app/conf/hibernate.
  • There’s no OpenSessionInView, so you’ll need to manage session flush() yourself. The easiest way to do this is to run your update/insert actions in a transaction – use GormHelper.withTransaction() for this (similar to calling withTransaction on a domain class in Grails)
  • Define data source info just like in Grails, in grails-app/conf/DataSource.groovy. It doesn’t make much sense to use dev or test mode, so just keep everything in the prod section.
  • There’s no Dialect autodetection, so you’ll need to specify that in DataSource.groovy, but you should be doing this in Grails anyway
  • There’s no Spring application context, so to access the Application, SessionFactory, and TransactionManager I’ve stored them in static fields in GormHelper

There’s a sample class that configures things and runs a test script – it’s called Tester in src/groovy. Just run “ant run” from the command line and it’ll compile and run this for you. This executes a script (scripts/Main.groovy) that creates some instances of the domain classes defined in grails-app/domain.

One significant issue that limits the usefulness of this is that as currently configured, you cannot execute anything other than dynamically loaded scripts. This is because Grails artifacts are loaded by a special Groovy/Grails classloader to support reloading and MetaClass magic methods. When I tried adding compiled domain classes to the classpath I was able to reference and import them but the MetaClass methods failed. I’ll have to take a look at how to get this working.


Thanks again to Jeremie Weldin. I did a pretty significant rewrite so I took the liberty of repackaging things under com.burtbeckwith but this wouldn’t have been possible without his original work.

You can download the code here. I’ve omitted the jar files from the zip – check out the README in the lib directory for the list of jars you’ll need to copy from your Grails installation.

9 Responses to “Using GORM outside of Grails”

  1. schleicher says:

    Thanks!
    I will try to use this soon…

  2. fcoffee says:

    good work!!

  3. […] | user-saved public links | iLinkShare 4 votesUsing GORM outside of Grails>> saved by jdbricker 2 days ago3 votesSeriously.>> saved by minaming 16 days ago2 votesA fluent […]

  4. Pablo says:

    Burt,

    Great work!!

    I’m still dealing with 1.0.3 to 1.1.1 migration. I had a trick to make my GroovyShell access GROM static injected methods from within a Grails application. I use GroovyShell to execute “dynamic” code (scripts), like custom validations.

    The trick was “new GroovyShell(grailsApplication.classLoader)”. But it is no longer working in 1.1.1 when deployed in Tomcat. That means, I get a MissingMethod exception when doing a get or list on a Domain class from the script.

    The WAR file includes the groovy’s source files now, and I’ve seen a post saying groovy in tomcat classpath causing problems. ;ay that be related ? Thank you Burt !!!

  5. WilliamWang says:

    Hi Burt,

    Thanks for your effort to make Gorm work outside of Grails. But I’m having trouble migrating it to Grails 1.3.5. I think it’s related to change from HibernateGrailsPlugin to HibernatePluginSupport. I changed following code:
    c = new HibernatePluginSupport().doWithDynamicMethods
    c.delegate = [application: application]
    c.call ctx

    But it doesn’t create those dynamic Gorm methods. Do you have any suggestions?

    Thanks,
    William

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.