Saturday, February 20, 2010

Hibernate + HSQLDB - problem with persisting entities.

Problem


Entities do not get stored when working with Hibernate+HSQLDB (embedded mode - file)


Description

I just wrote a very trivial piece of code to use Hibernate with HSQLDB. the main is like this:


public static void main(String[] args){


Session s = HibernateUtil.getSessionFactory().getCurrentSession();
s.beginTransaction();
Role role = new Role("grupa1");
s.persist(role);
s.getTransaction().commit();
}

I skip the hibernate configuration file. It was correct, very similar to what you can see in the hibernate tutorial.


  • Program exited normally,

  • no exceptions,

  • nothing incorrect in the log file,

  • console displayed the SQL inserts,

  • transaction status checked with wasCommited() method returned true.



However:

  • no data was stored in the database,

  • this piece of code worked well with PostgreSQL as a database,

  • similar piece of code worked well with HSQLDB in some long running aplications,

  • I ran this piece of code many times. The entity was persisted correctly only once or twice,

  • if I added Thread.sleep(3000) after the commit statement, the entity was saved in the database



The problem appears when the application terminates 'soon' after the transaction commit. ('soon' mean less than 1s). The data is not stored when HSQLDB is terminated soon after the transaction commit. I suppose that some operations required to store data were not executed by HSQLDB ( but... the application called commit() successfully. It looks quite dangerous... )

Solution:



I did two things. It solved the problem:

  • modify the jdbc connection url. Add the shutdown=true parameter:
    <property name="connection.url"&rt;jdbc:hsqldb:file:db/db;shutdown=true</property>

  • call sessionFactory.close() before exiting the application:


    public static void main(String[] args){


    Session s = HibernateUtil.getSessionFactory().getCurrentSession();
    s.beginTransaction();
    Role role = new Role("grupa1");
    s.persist(role);
    s.getTransaction().commit();
    HibernateUtil.getSessionFactory().close();
    }



It works now.

No comments:

Post a Comment