2011-05-25

Non JTA transactions with Hibernate, JBoss 6 and Spring 3

Hi there, I'm going to show you how to set up your JEE project to use non-JTA transactions with JBoss AS 6, Spring 3, Hibernate and JPA annotations.
Please note - integration tests don't require a database server running - they instantiate their own in-memory database server.

(Interested in JTA with Hibernate 3, Spring 3 and JBoss 6 instead?)

applicationContext.xml


This is our Spring config file.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
          http://www.springframework.org/schema/aop/spring-aop.xsd
          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd
          http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

   <bean id="entityManagerFactory"
       class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
       <property name="persistenceUnitName" value="Dogs" />
   </bean>

   <bean id="dogsDao" class="me.m1key.springtx.dao.DogsDaoImpl" />

   <bean id="dogsBean" class="me.m1key.springtx.beans.DogsBean"
       scope="singleton">
       <property name="dogsDao" ref="dogsDao" />
   </bean>

   <tx:annotation-driven transaction-manager="myTransactionManager" />

   <bean id="myTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
       <property name="entityManagerFactory" ref="entityManagerFactory" />
   </bean>

   <bean
       class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
What's worth noting is the transaction manager. Because we are not using JTA, we must explicitly provide the transaction manager for the application to use.

persistence.xml


Next, let's look at our persistence.xml file.

…
<persistence-unit name="Dogs" transaction-type="RESOURCE_LOCAL">       <non-jta-data-source>java:/DogsDS</non-jta-data-source>
      <class>me.m1key.springtx.entities.Dog</class>

      <properties>
          <property name="hibernate.show_sql" value="true" />
          <property name="hibernate.format_sql" value="true" />
          <property name="hibernate.hbm2ddl.auto" value="create" />
      </properties>
  </persistence-unit>
...
What we have here is a persistence unit called Dogs. The transaction type is RESOURCE_LOCAL - that tells the container not to use JTA. Below we specify JNDI data source name, entity classes and some properties. Note I don't have to specify typical data source properties (user name, password, url) - that's because they don't belong here. We define data source properties in JBoss.

dogs-ds.xml


This is a standard JBoss data source file. It must be called X-ds.xml.

<?xml version="1.0" encoding="UTF-8"?>

<datasources>
   <local-tx-datasource>

       <jndi-name>DogsDS</jndi-name>
       <connection-url>jdbc:hsqldb:hsql://localhost/dogsdb</connection-url>
       <driver-class>org.hsqldb.jdbcDriver</driver-class>
       <user-name>sa</user-name>
       <password></password>
       <min-pool-size>5</min-pool-size>
       <max-pool-size>20</max-pool-size>
       <idle-timeout-minutes>0</idle-timeout-minutes>
       <track-statements />
       <prepared-statement-cache-size>32</prepared-statement-cache-size>
       <metadata>
           <type-mapping>Hypersonic SQL</type-mapping>
       </metadata>
   </local-tx-datasource>
</datasources>
Nice and simple.

DAO


Last but not least, DAO that uses this setup.

   @PersistenceContext
   private EntityManager em;

   @SuppressWarnings("unchecked")
   @Transactional(readOnly = true)
   public List<Dog> retrieveAllDogs() {
       return em.createQuery("from Dog").getResultList();
   }

That's it! To run this example you need a database server running. I'm using HSQLDB. You can download source code and there is a batch file there that runs this HSQLDB server. The application is to be deployed on JBoss 6.

You call the transactional operation by accessing http://localhost:8080/springtx-nonjta-0.0.1-SNAPSHOT/myurl.

No comments:

Post a Comment