Announcement Announcement Module
Collapse
No announcement yet.
Spring, Hibernate, JPA, Infinispan and Tomcat, how to expose the TransactionManager Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring, Hibernate, JPA, Infinispan and Tomcat, how to expose the TransactionManager

    Hi,

    I have the following setup. We are using Tomcat as the container. JPA is used to manage our entities, Hibernate is the JPA provider. We also use Infinispan as the L2C. On top of this everything is running within Spring.

    We have a spring-hibernate.xml file that is defined as:
    Code:
    <?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:aop="http://www.springframework.org/schema/aop"
    	xmlns:jee="http://www.springframework.org/schema/jee"
    	xmlns:lang="http://www.springframework.org/schema/lang"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:util="http://www.springframework.org/schema/util"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-3.0.xsd
    		http://www.springframework.org/schema/aop http://www.springframework.org/schem...ng-aop-3.0.xsd
    		http://www.springframework.org/schema/jee http://www.springframework.org/schem...ng-jee-3.0.xsd
    		http://www.springframework.org/schema/lang http://www.springframework.org/schem...g-lang-3.0.xsd
    		http://www.springframework.org/schema/tx http://www.springframework.org/schem...ing-tx-3.0.xsd
    		http://www.springframework.org/schema/util http://www.springframework.org/schem...g-util-3.0.xsd">
    
    	<!-- use annotations for transaction management -->
        <tx:annotation-driven transaction-manager="transactionManager"/>
    
    	<!-- Process the PersistenceUnit and PersistenceContext annotations -->
     	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
    
    	<!-- spring's simple connection data source -->
    	<bean id="dataSource.hsqldb" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true" scope="singleton">
    		<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
    		<property name="url" value="${datasource.url}" />
    		<property name="username" value="" />
    		<property name="password" value="" />
    	</bean>
    
    	<!-- application datasource -->
    	<bean id="dataSource.jndi" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
        	<property name="jndiName" value="java:comp/env/jdbc/ds" />
      	</bean>
    	
    	<!-- official dataSource -->
    	<alias alias="dataSource" name="${data.source.id}" />
    	
    	<!-- Transaction Manager -->
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
            <property name="dataSource" ref="dataSource" />
        </bean>  
    
    	<!-- Transaction Template -->
    	<bean id="org.springframework.transaction.support.TransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" >
    		<property name="transactionManager" ref="transactionManager"/>
    	</bean>
    
        <!-- Hibernate/JPA configuration -->
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="jpa" />
            <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
            <property name="dataSource" ref="dataSource" />
            <property name="jpaDialect">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
            </property>
    
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="showSql" value="false" />
                    <property name="generateDdl" value="true" /> 
                    <property name="databasePlatform" value="${hibernate.dialect}" />
                </bean>
            </property>
        </bean>
    </beans>
    We also have the following persistence.xml file
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence
        xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
        version="2.0">
    
        <persistence-unit name="jpa">
    
            <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    
            <properties>
    
                <property name="hibernate.cache.infinispan.cfg" value="infinispan-config.xml"/>
                <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/>
                <property name="hibernate.cache.infinispan.cachemanager" value="java:CacheManager/entity" />
                <property name="hibernate.cache.infinispan.use_synchronization"  value="true"/>
                <property name="hibernate.cache.infinispan.statistics" value="true" />
    
                <property name="hibernate.cache.use_second_level_cache" value="true" />
                <property name="hibernate.cache.use_query_cache" value="true" />
                <property name="hibernate.generate_statistics" value="true" />
    
                <property name="hibernate.cache.use_structured_entries" value="true" />
               
            </properties>
    
        </persistence-unit>
    </persistence>
    I need to configure Infinispan to use the same transaction manager as JPA (Hibernate). I am stumbling upon the fact that we have defined a jpa transaction but I can't see how I can retrieve the JTA from it. On the other side if I define the JTA transaction how do I tell it to use the entity manager?

    I understand that I could also specify a transaction manager lookup class in the persistence xml such as:
    Code:
    <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />
    But since I am using Tomcat I have to somehow wire it via JNDI according to this documentation:
    https://docs.jboss.org/author/displa...Cache+Provider

    I am bit lost could anyone point me to the right direction?

    Thank you.

  • #2
    JPA != JTA... So if you use JpaTransactionManager you aren't using JTA and also cannot use JTA. You have to configure the JtaTransactionManager JTA and LOCAL transactions work in a different manner and you don't tell the JtaTransactionManager which resources to manage, the resources to manage register themselves (hence the need for the explicit transaction.manager_lookup_class).

    Tomcat doesn't have native JTA and you will have to use another solution like Atomikos to enable JTA transactions. If you switch to, for instance, JBoss then you have a server which supports transactions.

    Comment


    • #3
      Hi,

      I understand that the JpaTransactionManager is not the right option.

      I was under the impression I could configure JPA to use JTA by specifying the hibernate.transaction.manager_lookup_class property in the persistence.xml file, am I wrong?
      Since I am using JPA, how would I define an EntityManager that is associated with JTA?

      From your response I understand my only option is to define a JtaTransactionManager, and since I am using Tomcat, I have to rely on Spring org.springframework.transaction.jta.JtaTransaction Manager, but I have to configure it to use a third party, is that right?

      Thank you.

      Comment

      Working...
      X