Skip to content

Spring, JPA/JTA, and multiple persistence units, with view transactions

I have grappled with this topic before. Tonight, after 13 hours of struggle, I finally got my web app perfected in this regard.

It all started when I needed to start the Transaction out in the view, i.e. as soon as the resource is opened on the HTTP side (rather than when the database service layer is called). I’m using JPA for a number of reasons;

  1. I need to access multiple databases each with a different schema (this means different connections)
  2. They need to have XA transactions.
  3. I’d like the transactions managed by the container (JTA).

JPA provides all these things easily without all the complex Hibernate.xbm.xml mapping files and what-have-you.

The trick to starting the transaction with the web session is to use spring’s OpenEntityManagerInViewFilter. Unfortunately I was using  PersistenceAnnotationBeanPostProcessor to manage my multiple persistence units. The filter wants to know what EntityManagerFactory it should bind to, and fair enough. But with my minimal configuration, there was no addressable EntityManagerFactory!

The solution was to stop the PersistenceAnnotationBeanPostProcessor from doing the JNDI look ups and bind each PersistenceUnit into the Spring context with a manual JNDI lookup;

  <tx:annotation-driven />
  <tx:jta-transaction-manager />

  <bean id="pabpp" 
   class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
  <jee:jndi-lookup id="onePU" jndi-name="persistence/onePU" />
  <jee:jndi-lookup id="twoPU" jndi-name="persistence/twoPU" />
  <jee:jndi-lookup id="threePU" jndi-name="persistence/threePU" />

then, in the web.xml the ViewFilter could be bound explicitly to the required persistence unit, in this case “onePU”. A fuller explanation can be found on my spring source forum post here; http://forum.springsource.org/showthread.php?115844-OpenEntityManagerInViewFilter-with-JPA-PersistenceAnnotationBeanPostProcessor

Overall, this is now quite an elegant solution.

UPDATE. More documentation of the solution and the various configurations at the Spring forum here: http://forum.springsource.org/showthread.php?115587-Example-for-using-two-databases-w-Spring-amp-JTA-transaction-manager&p=383432#post383432