title: Configure an Atomikos UserTransactionManager for Hibernate in Spring Batch
body: <p>What I need to do is a distributed transaction over three distinct Oracle databases. One of each must be accessed through JDBC, the two others through Hibernate. Here is my Atomikos configuration : </p>
  
  <pre><code>&lt;bean id="mainDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
      init-method="init" destroy-method="close"&gt;
      &lt;property name="xaDataSourceClassName" value="${mainDataSource.jdbc.className}" /&gt;
      &lt;property name="uniqueResourceName" value="${mainDataSource.jdbc.uniqueName}" /&gt;
      &lt;property name="poolSize" value="${mainDataSource.jdbc.maxPoolSize}" /&gt;
      &lt;property name="testQuery" value="${mainDataSource.jdbc.testQuery}" /&gt;
      &lt;property name="xaProperties"&gt;
          &lt;props&gt;
              &lt;prop key="URL"&gt;${mainDataSource.jdbc.url}&lt;/prop&gt;
              &lt;prop key="user"&gt;${mainDataSource.jdbc.user}&lt;/prop&gt;
              &lt;prop key="password"&gt;${mainDataSource.jdbc.password}&lt;/prop&gt;
          &lt;/props&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="optionalDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
      init-method="init" destroy-method="close"&gt;
      &lt;property name="xaDataSourceClassName" value="${optionalDataSource.jdbc.className}" /&gt;
      &lt;property name="uniqueResourceName" value="${optionalDataSource.jdbc.uniqueName}" /&gt;
      &lt;property name="poolSize" value="${optionalDataSource.jdbc.maxPoolSize}" /&gt;
      &lt;property name="testQuery" value="${optionalDataSource.jdbc.testQuery}" /&gt;
      &lt;property name="xaProperties"&gt;
          &lt;props&gt;
              &lt;prop key="URL"&gt;${optionalDataSource.jdbc.url}&lt;/prop&gt;
              &lt;prop key="user"&gt;${optionalDataSource.jdbc.user}&lt;/prop&gt;
              &lt;prop key="password"&gt;${optionalDataSource.jdbc.password}&lt;/prop&gt;
          &lt;/props&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="eventDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
      init-method="init" destroy-method="close"&gt;
      &lt;property name="xaDataSourceClassName" value="${eventDataSource.jdbc.className}" /&gt;
      &lt;property name="uniqueResourceName" value="${eventDataSource.jdbc.uniqueName}" /&gt;
      &lt;property name="poolSize" value="${eventDataSource.jdbc.maxPoolSize}" /&gt;
      &lt;property name="testQuery" value="${eventDataSource.jdbc.testQuery}" /&gt;
      &lt;property name="xaProperties"&gt;
          &lt;props&gt;
              &lt;prop key="URL"&gt;${eventDataSource.jdbc.url}&lt;/prop&gt;
              &lt;prop key="user"&gt;${eventDataSource.jdbc.user}&lt;/prop&gt;
              &lt;prop key="password"&gt;${eventDataSource.jdbc.password}&lt;/prop&gt;
          &lt;/props&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="atomikosTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp"
      init-method="init" destroy-method="shutdownForce"&gt;
      &lt;constructor-arg&gt;
          &lt;props&gt;
              &lt;prop key="com.atomikos.icatch.service"&gt;com.atomikos.icatch.standalone.UserTransactionServiceFactory
              &lt;/prop&gt;
              &lt;prop key="com.atomikos.icatch.tm_unique_name"&gt;${transactionmanager.atomikos.tmId}&lt;/prop&gt;
              &lt;prop key="com.atomikos.icatch.enable_logging"&gt;${transactionmanager.atomikos.enablelogging}&lt;/prop&gt;
              &lt;prop key="com.atomikos.icatch.output_dir"&gt;${transactionmanager.atomikos.console}&lt;/prop&gt;
              &lt;prop key="com.atomikos.icatch.log_base_dir"&gt;${transactionmanager.atomikos.tmLog}&lt;/prop&gt;
              &lt;prop key="com.atomikos.icatch.log_base_name"&gt;${transactionmanager.atomikos.tmLogBaseName}&lt;/prop&gt;
          &lt;/props&gt;
      &lt;/constructor-arg&gt;
  &lt;/bean&gt;
  
  &lt;bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"
      depends-on="atomikosTransactionService"&gt;
      &lt;property name="transactionTimeout" value="300" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
      init-method="init" depends-on="atomikosTransactionService"
      destroy-method="close"&gt;
      &lt;!-- when close is called, should we force transactions to terminate or 
          not? --&gt;
      &lt;property name="forceShutdown" value="true" /&gt;
      &lt;property name="startupTransactionService" value="false" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="mainTransactionManager"
      class="org.springframework.transaction.jta.JtaTransactionManager"&gt;
      &lt;property name="transactionManager" ref="atomikosTransactionManager" /&gt;
      &lt;property name="userTransaction" ref="atomikosUserTransaction" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- Der mainTransactionManager ist der Default-TransactionManager von Spring. --&gt;
  &lt;alias name="mainTransactionManager" alias="transactionManager" /&gt;
  </code></pre>
  
  <p>The Hibernate configuration is inspired by the solution found on <a href="https://stackoverflow.com/questions/20681245/how-to-use-atomikos-transaction-essentials-with-hibernate-4-3">this topic</a> : </p>
  
  <pre><code>&lt;!-- inject the Atomikos transaction manager into a Spring Hibernate adapter 
      for JTA Platform --&gt;
  &lt;bean id="springJtaPlatformAdapter"
      class="my.domain.spring.hibernate.jta.SpringJtaPlatformAdapter"&gt;
      &lt;!-- the mainTransactionManager is defined in ora_jtam_atomikos.xml imported --&gt;
      &lt;property name="jtaTransactionManager" ref="mainTransactionManager" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="entityManagerFactoryEVL"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      depends-on="mainTransactionManager,springJtaPlatformAdapter"&gt;
      &lt;property name="persistenceXmlLocation" value="classpath:evl_persistence.xml" /&gt;
      &lt;property name="persistenceUnitName" value="evlPersistenceUnit" /&gt;
      &lt;property name="dataSource" ref="optionalDataSource" /&gt;
      &lt;property name="loadTimeWeaver"&gt;
          &lt;bean
              class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /&gt;
      &lt;/property&gt;
      &lt;property name="jpaPropertyMap" ref="jpaPropertyMapEVL"&gt;&lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;util:map id="jpaPropertyMapEVL"&gt;
      &lt;entry key="hibernate.hbm2ddl.auto" value="validate" /&gt;
      &lt;entry key="hibernate.show_sql" value="false" /&gt;
      &lt;entry key="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /&gt;
      &lt;entry key="hibernate.transaction.jta.platform"
          value="my.domain.spring.hibernate.jta.SpringJtaPlatformAdapter" /&gt;
  &lt;/util:map&gt;
  
  &lt;bean id="entityManagerFactoryVVL"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      depends-on="mainTransactionManager,springJtaPlatformAdapter"&gt;
      &lt;property name="persistenceXmlLocation" value="classpath:vvl_persistence.xml" /&gt;
      &lt;property name="persistenceUnitName" value="vvlPersistenceUnit" /&gt;
      &lt;property name="dataSource" ref="eventDataSource" /&gt;
      &lt;property name="loadTimeWeaver"&gt;
          &lt;bean
              class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /&gt;
      &lt;/property&gt;
      &lt;property name="jpaPropertyMap" ref="jpaPropertyMapVVL"&gt;&lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;util:map id="jpaPropertyMapVVL"&gt;
      &lt;entry key="hibernate.hbm2ddl.auto" value="validate" /&gt;
      &lt;entry key="hibernate.show_sql" value="false" /&gt;
      &lt;entry key="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /&gt;
      &lt;entry key="hibernate.transaction.jta.platform"
          value="my.domain.spring.hibernate.jta.SpringJtaPlatformAdapter" /&gt;
  &lt;/util:map&gt;
  </code></pre>
  
  <p>And the small class named SpringJtaPlatformAdapter :</p>
  
  <pre><code>public class SpringJtaPlatformAdapter extends AbstractJtaPlatform {
    private static final long serialVersionUID = -7030175748923257913L;
    private static TransactionManager sTransactionManager;
    private static UserTransaction sUserTransaction;
  
    @Override
    protected TransactionManager locateTransactionManager() {
      Assert.notNull(sTransactionManager, "TransactionManager has not been setted");
      return sTransactionManager;
    }
  
    @Override
    protected UserTransaction locateUserTransaction() {
      Assert.notNull(sUserTransaction, "UserTransaction has not been setted");
      return sUserTransaction;
    }
  
    public void setJtaTransactionManager(JtaTransactionManager jtaTransactionManager) {
      sTransactionManager = jtaTransactionManager.getTransactionManager();
      sUserTransaction = jtaTransactionManager.getUserTransaction();
    }
  
  }
  </code></pre>
  
  <p>When I do run the batch, I could verified that :</p>
  
  <ol>
  <li>the <code>atomikosUserTransaction</code> and <code>atomikosTransactionManager</code> of
  Atomikos are constructed first</li>
  <li>the <code>mainTransactionManager</code> is initialized right after</li>
  <li>the <code>setJtaTransactionManager</code> method of my <code>SpringJtaPlatformAdapter</code> is called, both memory addresses for the <code>sTransactionManager</code> and <code>sUserTransaction</code> are consistent with the ones created before</li>
  <li>the <code>locateTransactionManager</code> of the <code>SpringJtaPlatformAdapter</code> is called twice (one for each persistence unit)</li>
  <li>my Hibernate code is then performed, my entities are correctly initialized</li>
  <li>the database which is accessed through JDBC is updated</li>
  <li>the databases which are accessed through Hibernate are NOT updated (as if a rollback took place)</li>
  </ol>
  
  <p>During the run, only one warning appears in the logs : </p>
  
  <pre><code>WARN main SessionFactoryImpl:1530 - HHH000008: JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()
  </code></pre>
  
  <p>Maybe that can help, I personnaly don't get the warning message.</p>
  
  <p>According to Maven, I'm using Spring ORM 3.2.0 with Hibernate 4.2.3 and Atomikos 3.8.0.</p>