2011-10-10 84 views
1

当我单独运行我的单元测试时,它们可以正常工作。 (省略断言)JPA错误:事务处理当前处于活动状态

@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>(); 

它看起来像问题

所以哈克的解决方法是使用本地即定义。

EntityManagerFactory factory = Persistence.createEntityManagerFactory("bw_beta"); 
    EntityManager entityManager = factory.createEntityManager(); 
    entityManager.getTransaction().begin(); 
    dao.save(l); 
    entityManager.persist(l); 
    entityManager.getTransaction().commit(); 

很确定有更好的方法 - 也许使用Spring?

+1

'EntityManagerHelper'内发生了什么? – axtavt

+0

@DataNucleus:他没有说他想要并行运行它们。 –

+0

什么是异常的堆栈跟踪? –

回答

1
  • 很确定有更好的方法 - 也许使用Spring?

是的,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); 

看起来真的很奇怪,因为通常你会一个DAO层封装entityManager,因此,所有你需要做的是dao.save(l)

0

对于可能有这个问题的人这是我如何解决它。我正在做多个保存,我一直得到这个错误。您不想在没有检查它是否处于活动状态的情况下开始多个事务。

if(!entityManager.getTransaction().isActive()) 
    entityManager.getTransaction().begin(); 
dao.save(l); 
entityManager.persist(l); 
entityManager.getTransaction().commit(); 

我实现了一个Singleton方法来处理它。

+2

错误的编码。您的实体经理仍然会尝试提交... – Andreas

相关问题