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>();
,这看起来像问题
所以一个 hacky 解决方法是使用本地定义,即。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("bw_beta");
EntityManager entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
dao.save(l);
entityManager.persist(l);
entityManager.getTransaction().commit();
很确定有更好的方法 - 也许使用 Spring?
When I run my unit tests in isolation they work fine ie. (omitted the asserts)
@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();
}
then running this individual test below no problem
@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();
}
When they run at same time in sequence I recieve that error - Transaction is currently active. Is there a way to allow each unit test to run only after a transaction from previous piece of work is not active? Should I be looking at Spring instead?
Update
The EntityManagerHelper gains access to the persistence context like so
emf = Persistence.createEntityManagerFactory("bw_beta");
threadLocal = new ThreadLocal<EntityManager>();
which looks like the problem
So a hacky workaround was to use define locally ie.
EntityManagerFactory factory = Persistence.createEntityManagerFactory("bw_beta");
EntityManager entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
dao.save(l);
entityManager.persist(l);
entityManager.getTransaction().commit();
Pretty sure there's a better way - maybe using Spring?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,Spring 清理了很多东西,并让您可以控制要在事务中运行的内容,而不会污染实际测试。
使用 Spring,您的测试将如下所示:
查看 测试 =>事务管理以获取更多详细信息。
PS 从您的示例来看:
看起来非常奇怪,因为通常您会将
entityManager
封装在 DAO 中,因此您需要做的就是dao。保存(l)
Yes, Spring cleans it up a lot and gives you control on what you'd like to run within a transaction without polluting the actual test.
With Spring, your tests would look something like this:
Take a look at Spring Documentation under Testing => Transaction Management to get more details.
P.S. From your example:
Looks really strange, as usually you would encapsulate
entityManager
within a DAO, so all you'd need to do isdao.save(l)
对于可能遇到此问题的任何人,这里是我的解决方法。我进行了多次保存,但一直收到此错误。您不想在未检查事务是否处于活动状态的情况下开始多个事务。
我实现了一个单例方法来处理它。
For anyone that may be having this issue here is how I resolved it. I was doing multiple saves and I kept getting this error. You do not want to begin multiple transactions without checking if it is active.
I implemented a Singleton approach to handle it.