Configuring Spring + Hibernate JPA Transaction Manager through JTA

11,944

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/

Share:
11,944
Gabriel Sanmartin
Author by

Gabriel Sanmartin

Updated on August 14, 2022

Comments

  • Gabriel Sanmartin
    Gabriel Sanmartin over 1 year

    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>