May 12, 2003

Porting to Hibernate 2

We’ve been using Hibernate 1.2.x as a JMX service with JBoss to do our object persistence. We’ve not taking advantage of all its features, but it works very well.

Recently we needed a feature that we could get only with 2.x (update only changed fields), so I went ahead and bit the bullet to convert the application. It was a fairly easy task -- this document outlines most of the necessary changes. A couple more I'd add:

There is no Datastore object
I ran into this when translating our MBean. (We use this instead of the one shipped with Hibernate to work with the code generation system more smoothly.) Instead of defining a Datastore object and assigning the mapping files to it using storeResource and building the SessionFactory from it, you create a Configuration object to do much the same thing. So we used to have:

import cirrus.hibernate.Datastore;
import cirrus.hibernate.Environment;
import cirrus.hibernate.Hibernate;
...
public void startService()
{
    ...
    // Define Properties object 'props' from information
    // read from MBean configuration and elsewhere
    Datastore ds = Hibernate.createDatastore();
    String[] mappingFiles = getMapResources().split( ", " );
    try
    {
        ClassLoader cl = Thread.currentThread.getContextClassLoader();
        for ( int i = 0; i < mappingFiles.length; i++ )
        {
            ds.storeResource( mappingFiles[i], cl );
        }
        ds.buildSessionFactory( props );
    ...

Now it's:

import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.cfg.Environment;
....
public void startService()
{
    ...
    // Define Properties object 'props' from information
    // read from MBean configuration and elsewhere
    Configuration cfg = new Configuration();
    String[] mappingFiles = getMapResources().split( ", " );
    try
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        for ( int i = 0; i < mappingFiles.length; i++ )
        {
             cfg.addInputStream( cl.getResourceAsStream( mappingFiles[i] ) );
        }
        cfg.setProperties( props );
        cfg.buildSessionFactory();
    ...        

Not too much of a change. Note also that the Environment class moved to net.sf.hibernate.cfg.</b>

Change element in composite-id
You'll need to change the property element to a key-property element in any composite-id declarations. (For those of us using tables with multiple-field primary keys...)

Now: on to register the Interceptor so we can report which fields have changed in the object...

Next: Comparing languages
Previous: You say you want a revolution