java - JPA错误: Transaction is currently active

标签 java spring 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();
}

当它们按顺序同时运行时,我收到该错误 - 事务当前处于 Activity 状态。有没有办法允许每个单元测试仅在前一项工作的事务不活动后运行?我应该看看 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?

最佳答案

  • 很确定有更好的方法 - 也许使用 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);

看起来很奇怪,因为通常您会将 entityManager 封装在 DAO 中,因此您需要做的就是 dao.save(l)

关于java - JPA错误: Transaction is currently active,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7709583/

相关文章:

java - 使用 controlTransfer 与 USB 设备通信

java - 如何在谷歌地图android中添加hashmap?

java - WebLogic - 在 WebLogic Server 中部署 Spring Boot war

java - Spring查询字符串简单验证?

java - Hibernate JPA 父子映射

java - 覆盖 Hibernate 注解

java - 事务和 JPA/Persistence.xml

java - 如何访问docker内Java应用程序编写的文本文件

java - 如何在 Java Web 应用程序中声明启动 Hook

java - 关于Springaspectj加载时织入执行顺序