We are using SpringJUnit4ClassRunner for our DAO tests, the tests passed when they were run in Eclipse, but not in Maven. One of the test classes failed with HibernateSystemException:
org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
Google search gave me some clue about the problem had something to do with cascading style, transaction, and duplication but they didn't lead me anywhere. I broke at AbstractPersistentCollection.setCurrentSession to find out that the session/session factory (DAOs are instances of HibernateDaoSupport) assigned to one of the DAOs was different.
A second look at the test class which had:
@Autowired
BillingInvoiceDao $;
BillingOrderDao orderDao;
BillingItemDao itemDao;
MembershipDao membershipDao;
@Override
protected void setUpDataAccessObjects() {
membershipDao = DataAccessObjectHelper.getDataAccessObject(MembershipDao.class);
itemDao = DataAccessObjectHelper.getDataAccessObject(BillingItemDao.class);
orderDao = DataAccessObjectHelper.getDataAccessObject(BillingOrderDao.class);
}
I found out that BillingInvoiceDao was not a proxy instance but the other DAOs are. The log may explain something:
[07-11 09:19:30] DEBUG AutowiredAnnotationBeanPostProcessor [main]: Autowiring by type from bean name 'itest.net.aflexi.cdn.billing.HibernateBillingInvoiceDaoTest' to bean named 'billingInvoiceDao'
[07-11 09:19:30] DEBUG DefaultListableBeanFactory [main]: Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
[07-11 09:19:30] DEBUG DefaultListableBeanFactory [main]: Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
[07-11 09:19:30] DEBUG AnnotationTransactionAttributeSource [main]: Adding transactional method [testCrud] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT]
[07-11 09:19:30] DEBUG AnnotationAwareAspectJAutoProxyCreator [main]: Creating implicit proxy for bean 'itest.net.aflexi.cdn.billing.HibernateBillingInvoiceDaoTest' with 0 common interceptors and 1 specific interceptors
[07-11 09:19:30] DEBUG JdkDynamicAopProxy [main]: Creating JDK dynamic proxy: target source is SingletonTargetSource for target object [itest.net.aflexi.cdn.billing.HibernateBillingInvoiceDaoTest@17afcff]
[07-11 09:19:30] DEBUG AnnotationTransactionAttributeSource [main]: Adding transactional method [testCrud] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT]
[07-11 09:19:30] DEBUG TransactionalTestExecutionListener [main]: Explicit transaction definition [PROPAGATION_REQUIRED,ISOLATION_DEFAULT] found for test context [[TestContext@134b58c testClass = HibernateBillingInvoiceDaoTest, locations = array['classpath:spring/dataAccessTestContext.xml', 'classpath:spring/dataAccessTestContext.billing.xml'], testInstance = itest.net.aflexi.cdn.billing.HibernateBillingInvoiceDaoTest@17afcff, testMethod = testCrud@HibernateBillingInvoiceDaoTest, testException = [null]]]
[07-11 09:19:30] DEBUG TransactionalTestExecutionListener [main]: Retrieved @TransactionConfiguration [@org.springframework.test.context.transaction.TransactionConfiguration(defaultRollback=true, transactionManager=mainTxManager)] for test class [class itest.net.aflexi.cdn.billing.HibernateBillingInvoiceDaoTest]
[07-11 09:19:30] DEBUG TransactionalTestExecutionListener [main]: Retrieved TransactionConfigurationAttributes [[TransactionConfigurationAttributes@ddc524 transactionManagerName = 'mainTxManager', defaultRollback = true]] for class [class itest.net.aflexi.cdn.billing.HibernateBillingInvoiceDaoTest]
[07-11 09:19:30] DEBUG DefaultListableBeanFactory [main]: Returning cached instance of singleton bean 'mainTxManager'
[07-11 09:19:30] DEBUG TransactionalTestExecutionListener [main]: Executing @BeforeTransaction method [public void net.aflexi.cdn.core.test.AbstractDaoTest.setUpBeforeTransaction() throws java.lang.Exception] for test context [[TestContext@134b58c testClass = HibernateBillingInvoiceDaoTest, locations = array['classpath:spring/dataAccessTestContext.xml', 'classpath:spring/dataAccessTestContext.billing.xml'], testInstance = itest.net.aflexi.cdn.billing.HibernateBillingInvoiceDaoTest@17afcff, testMethod = testCrud@HibernateBillingInvoiceDaoTest, testException = [null]]]
[07-11 09:19:30] DEBUG DefaultListableBeanFactory [main]: Returning cached instance of singleton bean 'membershipDao'
That transaction propagation happened after autowiring of beans. The fix of my problem is to @Autowired all DAOs (so that they are consistent) or assign them via the DataAccessObjectHelper as shown in the snippet.
Hope this helps.
No comments:
Post a Comment