Java – Configuring Spring + Hibernate JPA Transaction Manager through JTA

hibernatejavajpaspring

I previously had this config for Hibernate using RESOURCE-LOCAL transaction type:

persistence.xml:

<persistence-unit name="myPU" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

</persistence-unit>

applicationContext (dataaccess bit):

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"></bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter" ref="jpaAdapter" />
    <property name="persistenceUnitName" value="myPU"/>
    <property name="jpaProperties">
        <props>
            <prop key="javax.persistence.validation.mode">none</prop>
        </props>
    </property>
</bean>

<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <!-- Are there any other properties required? -->
</bean>

<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

    <property name="showSql" value="true" />
    <property name="generateDdl" value="false" />
</bean>

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/CNTXESDB" />
    <property name="lookupOnStartup" value="true" />
    <property name="cache" value="true" />
    <property name="proxyInterface" value="javax.sql.DataSource" />
</bean>

But this kind of transaction seems not to work with Glassfish, so I had to switch to JTA transactions.

The problem is — to get Spring to manage transaction creation (through @Transactional) I need to define a TransactionManager bean but JtaTransactionManager included in spring-tx does not accept an entityManagerFactory bean, so it does not know where the entityManager is in order to open/close/flush Hibernate session.

So how can I configure Spring with Hibernate to use JTA transactions?

EDIT:
turns out you can use RESOURCE_LOCAL transactions with Glassfish, but somehow you cannot have a persistence.xml file. I renamed this file to my_persistence.xml and configured LocalContainerEntityManagerFactoryBean like this:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="jpaAdapter" />
        <property name="persistenceUnitName" value="myPU"/>
        <property name="persistenceXmlLocation" value="classpath:META-INF/my_persistence.xml" />
        <property name="jpaProperties">
            <props>
                <prop key="javax.persistence.validation.mode">none</prop>
            </props>
        </property>
    </bean>

Best Solution

I had a similar problem and finally I solved as you can see in this little demo: https://github.com/miguelangelprogramacion/spring4_jpa_hibernate

With [1] as a reference, I prefer to use Spring's Transaction Support before JTA.

Also, I've used an annotation based approach.

[1] http://spring.io/blog/2011/08/15/configuring-spring-and-jta-without-full-java-ee/