Atomikos Forum |
|
Using Spring, JPA/Hibernate and dbUnit with Spring Transactions.
We're adding 2 datasources to the app, so I setup Atomikos for the JTA manager. Our existing dbUnit tests that work fine under local transactions fail with the global transactions because the dbUnit data verification does not see the uncommitted data as happens with local/jdbc transactions: A simple dbUnit DAO persist test with these steps fails: - create entity - dao.persist(entity) - the dao uses the injected entityManager - no commit done - dbunit verify, basically: - gets connection from datasource - injecting an instance of AtomikosDataSourceBean - calls "select * from thetable" - gets 0 results If I inject the UserTransaction instance into the test and call commit() after the persist, the dbUnit verification passes. How do I configure this so the dbUnit dataSource.getConnection() call will see the uncommitted transaction data in progress? As part of dbUnit configuration, I've configured the dbUnit class DataSourceDatabaseTester with the same instance of AtomikosDataSourceBean that the EntityManager receives. DataSourceDatabaseTester takes the DataSource and calls getConnection() on it when called for. <bean id="databaseTester" class="org.dbunit.DataSourceDatabaseTester"> <constructor-arg ref="dataSource" /> <property name="tearDownOperation"> <util:constant static-field="org.dbunit.operation.DatabaseOperation.DELETE_ALL" /> </property> </bean> I've configured the creation of the JTA related Spring beans like this: <tx:annotation-driven /> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="atomikosTransactionManager" /> <property name="userTransaction" ref="atomikosUserTransaction" /> </bean> <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="dbDataSourceEmbedded" class="org.apache.derby.jdbc.EmbeddedXADataSource"> <property name="databaseName" value="${cmr.databaseName.cmr3}" /> <property name="createDatabase" value="${cmr.createDatabase.cmr3}"/> <property name="connectionAttributes" value="${cmr.connectionAttributes.cmr3}" /> </bean> (2 more EmbeddedXADataSource configured the same) <bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="cmr3DataSource" /> <property name="xaDataSource" ref="${cmr.dbDataSourceBeanId.cmr3}" /> <property name="minPoolSize" value="${cmr.minPoolSize.cmr3}" /> <property name="maxPoolSize" value="${cmr.maxPoolSize.cmr3}" /> <property name="defaultIsolationLevel" value="${cmr.defaultIsolationLevel.cmr3}" /> </bean> (2 more AtomikosDataSourceBean configured the same) Then 3 LocalContainerEntityManagerFactoryBean configurations each using one of the 3 dataSource beans. So Atomikos is serving up the connection to dbUnit, but is it not in same transaction? Can JTA do this? If not is there another approach? I also set transaction isolation to 1 (read uncommitted) via defaultIsolationLevel on AtomikosDataSourceBean in case that would help, but it made no difference. I see isolation level is 1 on the connection in my log statements, so I know the setting worked. What is needed to have the dbUnit connection received from Atomikos see the uncommitted data?
This is what the entityManager bean configs look like:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="${persistenceUnitName}" /> <property name="persistenceUnitManager"> <bean class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"> <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" /> <property name="dataSources"> <map> <entry key="cmr3" value-ref="dataSource" /> </map> </property> <property name="persistenceUnitPostProcessors"> <bean class="net.sf.sidaof.spring.EntityPersistenceUnitPostProcessor"> <property name="packages" value="${entity.package.cmr}" /> </bean> </property> </bean> </property> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="${showSql}" /> <property name="generateDdl" value="${generateDdl}" /> <property name="database" value="DERBY"/> <property name="databasePlatform" value="${databasePlatform}" /> </bean> </property> <property name="jpaProperties"> <props> <prop key="hibernate.ejb.naming_strategy">${hibernate.ejb.naming_strategy} </prop> <prop key="hibernate.format_sql">${hibernate.format_sql} </prop> <prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments} </prop> <prop key="hibernate.generate_statistics">${hibernate.generate_statistics} </prop> <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup </prop> </props> </property> </bean> |