Category Archives: Hibernate

Fixing Intermittent Table Not Found Errors with JUnit when Using Hibernate SchemaExport and H2

As a part of my test suite, I run a series of tests using Hibernate and the h2 database (h2 seems to be the most lightweight java in memory database around at the moment). These tests run in memory and perform realively quickly, so are a part of my pre-commit build.

In order to move to a spot where the application upgrades work well, I’ve just removed the hbm2ddl.auto create-drop statements from my hibernate.xml file, and wanted to move to a programmatic use of the SchemaExport tool. This was more pain than expected, so I’m documenting what I had to do here.

From the javadoc, and Java Persistence with Hibernate, it looks like you can get away with the following code:

1: Configuration configuration = new Configuration().configure();
2: SchemaExport schemaExport = new SchemaExport(configuration);
3: schemaExport.create(false, true);

Unfortunately I found that this didn’t quite work. It seems that the connection/transactionality/connection pool combination of concerns would cause this kind of code to fail at various degrees. After much gnashing of teeth I ended up with the following code:

1: Configuration configuration = new Configuration().configure();
2: SessionFactory sessionFactory =

         configuration.buildSessionFactory();
3: Session session = sessionFactory.openSession();
4: Connection connection = session.connection();
5: SchemaExport schemaExport =

          new SchemaExport(configuration, connection);
6: schemaExport.execute(false, true, false, true);
7: session.close();

the critical differences are:

In lines 2-4 we are obtaining a connection to the database which is then used by the schema export tool. In line 6 we do the export using the execute command, passing in a bunch of booleans. This tell it execute command:

  • don’t output the sql to the console,
  • do execute on the database,
  • don’t execute drop statements, and
  • do execute create statements.

Finally in line 7, we close the session, ensuring jdbc connection is released and cleaned up. Now any intermittent problems caused by using schema export with h2 database should be avoided.

Howto Keep Version History in a Single Table Using Hibernate

 

Problem:

Keeping a history of data in a single table in hibernate, where all versions are treated as first class objects.

That is to say that every record in the database will be immutable. New records will be created with a new version number, but the old versions will never change. They are kept as the history of changes.

Solution:

When querying objects from hibernate ensure that they are initialised, and then detach them from the session:

Hibernate.initialize(result);
session.evict(result);

Then when saving the objects, ensure that the ID is null, and call thesession.save(businessObject) to save them.

//set the id to null to ensure that a new record is stored in the database.
businessObject.setId(null);
incrementVersion(businessObject);
session.save(businessObject);

The final part of the puzzle is to ensure that the class has it’s persistence properties set correctly, either by setting the annotations or configuring the xml file.

The important settings are:

  1. To help prevent updates, and improve performance set the mutable attribute on the class to false.
  2. The collection objects on the class have the lazy attribute set to false (ensuring that they are loaded when the object is retrieved, and the evicted object will work).

Following these steps will provide you with a versioned business object. It will be possible to retrive, and store the object to the database using the Hibernate search functionality.

Storing Large Strings with Hibernate 3

If you want to store a large string in hibernate 3 in a relatively transparent way, the text mapping type is your friend.  This will allow you to map a java String type to a database clob type, and store arbitary length large content items.  In previous versions (according to google) this took a fair bit of fiddling around, and required custom types (which required much magic to work in a cross platform manner).  Thankfully the text mapping type exists, making life much easier.

 

So in the old school pre 1.5 annotation world, we can take the class with a long string and map it using the code and mapping below:

class Profile {
    ...  
  private String bio;
    ...  
  public String getBio(){
    return bio;
  }

  public void setBio(String bio){
    this.bio=bio;
  }

}

and the mapping file:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="Profile" table="profiles">
        ...
        <property name="bio" type="text" length="
10485760"/>
    </class>
</hibernate-mapping>

This will let you store a large string in hibernate, automatically handling the mapping between clob data and string data.  The important parts of the xml snippet above are the type and length attributes.  Both are required to ensure that the clob will be created of the right length.  The default for the length is 255, which is great when you are storing shortish strings in a varchar, but not so good when you want a large string in a clob.