The following code and configuration files are for a unit test of a very basic DAO for a user (Person class). If the test is run once (1 time) there are no problems. If the test is run 4 times (ie. copy the testPersonGetByLoginId 3 times and rename it slightly differently) there are no problems. When I add a fifth version of the test, suddenly the tests hang, with no further information in log files or in the junit output to tell what the problem is.
(I realize this example isn't very realistic but I originally found this problem when I was doing all sorts of different tests and the tests always failed when there were 5 tests - this is just a simple demo of the problem).
I have a theory that it might have something to do with transactions but I'm stumped and I've been searching the forums for several days looking for an idea.
Details: testing using an in-memory HSQLDB, Hibernate 3.1, Spring 1.2.6
Code follows:
Code:
public class DbTestCase extends TestCase {
// Constants
protected static final AbstractApplicationContext springContext = new FileSystemXmlApplicationContext(
new String[] {
"build/WEB-INF/conf/TEST-applicationContext-datasource.xml",
"build/WEB-INF/conf/applicationContext-hibernate.xml" });
protected static final HibernatePersonDAO hPersonDao = (HibernatePersonDAO) springContext
.getBean("HibernatePersonDAO");
protected static final TransactionDefinition td = new DefaultTransactionDefinition();
protected static final HibernateTransactionManager htxManager = (HibernateTransactionManager) springContext
.getBean("transactionManager");
protected void setUp() throws Exception {
super.setUp();
springContext.refresh();
}
protected void tearDown() throws Exception {
super.tearDown();
}
}
Code:
public class HibernatePersonDAOTest extends DbTestCase {
// Constants
private static final String LOGIN_ID = "loginId1";
private static final String PASSWORD = "password1";
private Person person;
private TransactionStatus txStatus;
protected void setUp() throws Exception {
super.setUp();
txStatus = htxManager.getTransaction(td);
// put a person and an author into the db to use
// in the tests
person = new Person();
person.setUserName(LOGIN_ID);
person.setPassword(PASSWORD);
hPersonDao.save(person);
}
// retrieve person using login id
public void testPersonGetByLoginId() {
Person newPerson = hPersonDao.getByLoginId(person.getUsername());
assertEquals(person, newPerson);
}
protected void tearDown() throws Exception {
htxManager.commit(txStatus);
super.tearDown();
person = null;
}
}
TEST-applicationContext-datasource.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value></property>
<property name="url">
<value>jdbc:hsqldb:mem:mydb</value></property>
<property name="username"><value>sa</value></property>
<property name="password"><value></value></property>
<property name="defaultAutoCommit"><value>false</value></property>
<property name="initialSize"><value>1</value></property>
<property name="removeAbandoned"><value>true</value></property>
<property name="removeAbandonedTimeout"><value>15</value></property>
<property name="logAbandoned"><value>true</value></property>
</bean>
<bean id="hibernateConfig" class="org.springframework.core.io.ClassPathResource">
<constructor-arg>
<value>TEST-hibernate.cfg.xml</value>
</constructor-arg>
</bean>
</beans>
applicationContext-hibernate.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="mappingLocations">
<list>
<value>classpath:/ca/utoronto/atrc/tile/person/Person.hbm.xml</value>
</list>
</property>
<property name="configLocation">
<ref bean="hibernateConfig" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="HibernatePersonDAO" class="ca.utoronto.atrc.tile.person.HibernatePersonDAO">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
</beans>
TEST-hibernate.cfg.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="hibernate.hbm2ddl.auto">create-drop</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.use_sql_comments">false</property>
</session-factory>
</hibernate-configuration>