indiWiz.com

Subhash's Tech Log

Unit Testing Hibernate Code With Derby

with 5 comments

We faced a scenario which I have faced before: our application uses Hibernate and Oracle Database. And every time we run tests, we had to configure the database specific to that system. I was fed up by this, and explored the possibility of running our code against a test DB. We finalized on Derby.

So the next step was configuring hibernate.cfg.xml. We did this:

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property>
        <property name="hibernate.connection.url">jdbc:derby:target/testdb;create=true</property>
        <property name="show_sql">true</property>
        <property name="dialect">org.hibernate.dialect.DerbyDialect</property>
        <property name="hbm2ddl.auto">create-drop</property>
    </session-factory>
</hibernate-configuration>

In the hibernate.connection.url property note the parameter create=true. This ensures when the JDBC layer establishes the connection, the Database will be created if it has not been created earlier. Another important parameter from testing perspective is: hbm2ddl.auto. The value set in this parameter is create-drop. This ensures if the tables that are mapped in *.hbm.xml files are not present in the Database, they will be created (during the creation of SessionFactory). And when the SessionFactory is closed, the tables will be dropped. Perfect for testing! Note that, if you want the database tables to persist, just give create instead of create-drop.

So where will the DB be created? This is specified in the hibernate.connection.url property. Note the string target/testdb. This is the folder where the DB will be created. Ensure that the relative folder target/ exists in this case (testdb will be automatically created because of the property create=true).

In some scenarios we might want to test the correctness of the application by manually verifying the database content. In such situation, as discussed previously, change the hbm2ddl.auto property to create. After that connect to that DB using the Derby command-line tool:

$ java -cp $JAVA_HOME/db/lib/derby.jar:$JAVA_HOME/db/lib/derbytools.jar \
   org.apache.derby.tools.ij

This will open the ij prompt. Connect to our DB using it:

ij> connect 'jdbc:derby:target/testdb';
ij> select * from __table__;

Isn’t it cool?

Written by Subhash Chandran

January 5th, 2009 at 8:10 pm

Posted in Java

Tagged with , ,

5 Responses to 'Unit Testing Hibernate Code With Derby'

Subscribe to comments with RSS or TrackBack to 'Unit Testing Hibernate Code With Derby'.

  1. The most disappointing thing about Derby though is the lack of sequences. See https://issues.apache.org/jira/browse/DERBY-712.

    Binil Thomas

    20 Jan 09 at 9:32 am

  2. We did not face this as limitation in our test code. Our actual code was on Oracle, and the test in Derby. The .hbm.xml had the following for the primary key field in Oracle:

    <generator class="sequence">
    <param name="sequence">sequence_name</param>
    </generator>

    and this for Derby:

    <generator class="identity"/>

    subwiz

    24 Jan 09 at 7:57 pm

  3. Hi,
    I’m not sure what kind of testing you’re talking about, but you may want to check out the unitils project at http://www.unitils.org/summary.html . Among other things using it enables easy setup and teardown of databases for testing. On a similar note, another project I’ve recently discovered and found very useful is Liquibase at http://www.liquibase.org/ This gives robust change managment of databases schemas etc rather than relying on Hibernate hbm2ddl.auto, which does not help with versioning or upgrades of the persistence layer.
    Cheers!
    Chas66

    chas66

    10 May 09 at 6:50 am

  4. Hi,
    I’m wondering how you would make Derby create and alter the tables given a specific DDL/DML instead of having Hibernate create the tables. That is, I would like use in the persistence.xml and have the tables created from a certain DDL (by Derby).

    My current problem is that in production I have a separate DDL and DML and only let Hibernate validate the schema; but I also want to use those DDL/DML in my unit tests instead of having Hibernate create the tables in a manner different from the DDL/DML.

    BP-2000

    2 Dec 10 at 7:27 pm

  5. Not working for me… getting NullPointer Exception at session.save(object);

    Parth

    23 Dec 10 at 9:18 pm

Leave a Reply