当我单独运行单元测试时,它们工作正常,即。 (省略断言)
@Test
public void testSave()
{
EntityManagerHelper emh = new EntityManagerHelper();
LevelDAO dao = new LevelDAO();
Level l = new Level();
l.setName("aname");
emh.beginTransaction();
dao.save(l);
emh.commit();
}
然后在下面运行此单独测试没问题
@Test
public void testUpdate()
{
EntityManagerHelper emh = new EntityManagerHelper();
LevelDAO dao = new LevelDAO();
Level l = new Level();
l.setName("bname");
l.setLevelid(1);
emh.beginTransaction();
dao.update(l);
emh.commit();
}
当它们按顺序同时运行时,我收到该错误 - 交易当前处于活动状态。是否有办法允许每个单元测试仅在上一个工作的事务未激活后运行?我应该看看Spring吗?
更新
EntityManagerHelper可以访问持久化上下文,如此
emf = Persistence.createEntityManagerFactory("bw_beta");
threadLocal = new ThreadLocal<EntityManager>();
看起来像问题
所以一个hacky解决方法是使用local local ie。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("bw_beta");
EntityManager entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
dao.save(l);
entityManager.persist(l);
entityManager.getTransaction().commit();
非常确定有更好的方法 - 也许使用Spring?
答案 0 :(得分:1)
是的,Spring会清理它并让您控制您在交易中运行的内容,而不会污染实际测试。
使用Spring,您的测试看起来像这样:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:META-INF/conf/spring/application-context.xml",
"classpath:META-INF/conf/spring/test-datasource-spring-config.xml" })
@TransactionConfiguration(transactionManager="txMgr", defaultRollback=false)
public class LevelDaoTest {
@Resource( name="levelDao" )
LevelDao levelDao;
@Test
public void shouldSaveNewLevels() {
Level l = new Level();
l.setName("aname");
levelDao.save(l);
// assert
}
@Test
public void shouldUpdateExistingLevels() {
Level l = new Level(); // or I would assume, you'd read this level back from DB, or set a proper ID, so the DAO will know to update it.. But that is besides the point
l.setName("bname");
levelDao.update(l);
// assert
}
}
查看Testing => Transaction Management下的Spring文档以获取更多详细信息。
P.S。从您的示例:
dao.save(l);
entityManager.persist(l);
看起来很奇怪,因为通常你会将entityManager
封装在一个DAO中,所以你需要做的就是dao.save(l)
答案 1 :(得分:0)
对于任何可能遇到此问题的人来说,我是如何解决它的。我正在进行多次保存,并且我一直收到此错误。您不希望在不检查它是否处于活动状态的情况下开始多个事务。
if(!entityManager.getTransaction().isActive())
entityManager.getTransaction().begin();
dao.save(l);
entityManager.persist(l);
entityManager.getTransaction().commit();
我实施了一种Singleton方法来处理它。