JTA transaction with a single database

You can find sample source code in the project DeploymentJBossJTA.

In order to use JTA you need to configure a transaction manager. This is specific for every application server. For the JBoss application server, you have to add the following properties to the hibernate.cfg.xml.

<property name="hibernate.transaction.factory_class">
  org.hibernate.transaction.JTATransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
  org.hibernate.transaction.JBossTransactionManagerLookup
</property>
<!--  jta is the short name for org.hibernate.context.JTASessionContext
and let Hibernate bind the session automatically to the JTA transaction.
This implies that Hibernate will close the session after the transaction.
<property name="hibernate.current_session_context_class">jta</property>

Add the following property, if you want Hibernate to close your session automatically, when you call commit or rollback.

<property name="transaction.auto_close_session">true</property>

Let’s have a look at the Hibernate pattern we get:

      Transaction tx = null;
      try {
         Session session = InitSessionFactory.getInstance().openSession();
         tx = session.beginTransaction();
         Invoice invoice = new Invoice();
//  This line is just to show that you can use getCurrentSession from now on
         InitSessionFactory.getInstance().getCurrentSession().save(invoice);
         tx.commit();
      } catch (RuntimeException e) {
         if (tx != null)
         {
            try {
               tx.rollback();
            } catch (HibernateException e1) {
               log.error("Error rolling back");
            }
         }
         throw e;
      }

There is a subtle difference. We call session.openSession instead of getCurrentSession. In a application server Hibernate needs to bind the session to a transaction before it is stored in a session context. The transaction is not available before having called session.beginTransaction. Therefore Hibernate places the session in the context after beginTransaction was called. Inside of the transaction you can use getCurrentSession.

Connection and JTA

If you use JTA you must use a datasource provided by your application server. This is normally a JNDI datasource. You can find a JNDI datasource in the sample project of this chapter.

Another option is to bind the factory to JNDI. You just have to specify the following in your hibernate.cfg.xml. This is useful to share a sessionFactory.

<property name="hibernate.session_factory_name">HibernateTest1</property>