<tx:annotation-driven proxy-target-class="true" />
<tx:jta-transaction-manager
transaction-manager="atomikosTransactionManager" />
<tx:annotation-driven transaction-manager="atomikosTransactionManager"
proxy-target-class="true" />
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
<property name="allowCustomIsolationLevels" value="true" />
</bean>
Your configuration is flawed and contains duplication, which probably, confuses spring. Both the JtaTransactionManager
as well as <tx:jta-transaction-manager />
create a JtaTransactionManager
.
Next your <tx:annotation-driven >
should point to a JtaTransactionManager
but nog it points to a UserTransactionManager
.
So first fix your configuration:
<tx:annotation-driven proxy-target-class="true" />
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
<property name="allowCustomIsolationLevels" value="true" />
</bean>
Assuming you are using a recent Spring 3.2 version instead of injecting the dataSource
property inject the jtaDataSource
on your LocalContainerEntityManagerFactoryBean
, next your jpaProperties
and jpaPropertiesMap
can be cleaned up.
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="xaDataSource" />
<property name="packagesToScan" value="com.xxx.model" />
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
</props>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
</bean>
</property>
</bean>
The hibernate.connection
properties are useless as you are injecting a Spring managed datasource. Due to the injection of the jtaDataSource
the jpaProperty for javax.persistence.transactionType
can be removed. The HibernateJpaVendorAdapter
already sets the HibernateJpaDialect
and you can use the databasePlatform
property to specify the dialect.
Regarding your datasources you should be using the Atomikos wrappers for the datasources so that they are aware of Atomikos. For this use the AtomikosDataSourceBean
instead of the xa provided datasource for your JDBC driver.
<bean id="xaDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
<property name="uniqueResourceName" value="xaDataSource"/>
<property name="xaProperties">
<props>
<prop key="url">${mysql_url}</prop>
<prop key="user">root</prop>
<prop key="password">xxx</prop>
</props>
</property>
</bean>
Finally you are using the BasicDataSource
as a reference to hibernate whereas you should use the xa enabled (and wrapped) datasource.