我有一个 POJO(在这个例子中是 Myclass),我在我的应用程序中保留/更新/删除它。
我使用监听器类检测对该对象的更改,然后在监听器类中将更改保存到另一个表。
Here is my class (dummy example) :
EntityListeners({MyListener.class})
class MyClass {
String name;
String surname;
/*...getters...setter..etc */
public void save() {
JPA.em().persist(this);
return this;
}
public void update() {
JPA.em().merge(this);
}
}
class MyListener {
@preUpdate
public void preUpdate() {
/*...some logic to save the changes irrelevant*/
someAuditObj.createWithData(.......);
someAuditObj.save();
}
}
我正在使用 play framework v2.1.3
构建我的网络应用程序,所有这一切都运行良好,我真的很高兴它的工作方式。
今天我更新了 play framework 到更新版本 v2.2.1
。
出于某种原因,当 MyClass
的实例发生更改并且监听器获取更改并尝试保存更改时,事务失败,我在日志中找到了这一点:
Caused by: java.lang.RuntimeException: No EntityManager bound to this thread
所以我花了一段时间才弄清楚由于某种原因事务没有传播到监听器,然后我尝试了一些方法来修复它(监听器类):
@preUpdate
public void preUpdate() {
/*...some logic to save the changes irrelevant*/
JPA.withTransaction(new F.Callback0() {
@Override
public void invoke() throws Throwable {
someAuditObj.createWithData(.......);
someAuditObj.save();
});
}
所以这修复了它,它像以前一样正常工作。
我的问题是:
- 为什么以前不用手动干预早期版本的 play 框架的事务就可以工作
- 有没有更好的方法可以更优雅地实现同样的目标(我不确定这个词是否合适)?
更新
这是我的 Controller 方法:
@Transactional
public Result updateName(Long id, String name){
MyClass c = MyClass.findById(id);
c.setName(name);
c.update();
return ok();
}
所以事务应该传播到所有方法,对吗?但为什么不也听听呢?
我的估计是这样的:
如果一个方法有@Transactional 注解那么所有在里面发生的调用都应该在一个事务中?
最佳答案
看来你遇到了和我一样的问题。看我的问题:https://github.com/playframework/playframework/issues/2042 相同的 JPA 代码适用于 2.1.0 但不适用于 2.2.1 所以我认为这是一个错误。
- Why did it work before without meddling manually with transactions with earlier version of play framework
- Is there a better way of achieving the same thing more elegantly (I'm not sure that is the right word for it)?
我们只能等到这个问题解决,或者等待 play2 开发人员在这个问题上解释一下如何使用线程和 JPA 事务。目前问题是开放的。
关于java - 没有 EntityManager 绑定(bind)到这个线程 JPA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19931811/