2
votes

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>
1
I suggest to rename the bean <bean id="entityManager" could be a problem.. Anyway follow this tutorialXstian
Obviously that will not work. You specified that you want to use JTA but in yuour configuration use local transactions. Either change your persistence.xml or configure JTA transactions correctly.M. Deinum
@M.Deinum what I am asking is just that: how to configure it properlyGabriel Sanmartin
Why would you need JTA there is nothing preventing you from using local transactions on glassfish. That is the point I was trying to make, if it doesn't work with resource-local it is because your setup is wrong. If you don't need JTA then don't use JTA.M. Deinum
Ah. Nice glassfish is trying to bootstrap JPA too. They are competing. Just remove persistence.xml you don't need it with Spring, or rename it and add the persistenceXml property to the LocalContainerEntityManagerFactoryBean to specify the new name/location of the file. Easiest is to just remove it.M. Deinum

1 Answers

2
votes

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/