Spring JUnit无法运行TransactionSynchronizationManager.bindResource,而Normal Spring Env Can

时间:2013-10-22 18:59:21

标签: spring junit

我有一个基于Spring / Hibernate的Web应用程序。现在我需要使用Spring JUnit 4为它编写集成测试。 这是我的测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "hibernateTransactionManager", defaultRollback = true)
@ContextConfiguration(locations = {"classpath:applicationContext-xxx.xml", "classpath:applicationContext-xxx.xml", "classpath:applicationContext-xxx.xml", "classpath:applicationContext-xxx.xml", "classpath:applicationContext-xxx.xml", "classpath:applicationContext-xxx.xml", "classpath:applicationContext.xml"})

public class TestXXX extends AbstractTransactionalJUnit4SpringContextTests {

@Test
public void testXXXExecute(){...}
}

通过测试环境的这个设置,我可以访问所有bean并使用sessionFactory bean从数据库中获取数据。

一个测试会出现问题,使用TransactionSynchronizationManager调用生产代码来实现两阶段提交。 代码如下所示:

TransactionSynchronizationManager.bindResource(sessionFactoryA, new SessionHolder(sessionA));
TransactionSynchronizationManager.bindResource(sessionFactoryB, new SessionHolder(sessionB));

代码在完整的Spring Framework运行的开发和生产环境中表现良好。在JUnit运行期间,例外是:

[junit] java.lang.IllegalStateException: Already value [org.springframework.orm.hibernate3.SessionHolder@6311e359] for key [org.hibernate.impl.SessionFactoryImpl@56d47236] bound to thread [main]

我不能在测试类中使用2行@TransactionConfiguration来定义对应于两个数据源和两个sessionFactory对象的两个事务管理器。我想知道AbstractTransactionalJUnit4SpringContextTests是否不能复制真正的Spring Framework的事务环境。

1 个答案:

答案 0 :(得分:0)

如果没有看到更多代码,很难确切地说出错误。在我过去看过这个错误的情况下,这是因为@ContextConfiguration中命名的文件互相包含。例如,您可能有文件

applicationContext-bean-cfg.xml

包括

applicationContext-hibernate-cfg.xml,但随后

@ContextConfiguration(locations = {"classpath:/applicationContext-bean-cfg.xml", "classpath:/applicationContext-hibernate-cfg.xml"})

要检查的另一件事是其中一个文件尚未定义事务管理器。