[英]JPA and Threads in play framework
我正在尝试创建一个多线程服务器。 问题是我收到以下错误: play.exceptions.JPAException:JPA上下文未初始化。 当在应用程序中找到使用@ javax.persistence.Entity批注注释的一个或多个类时,JPA实体管理器会自动启动。
我要做的是从新线程访问数据库这里是代码
package controllers;
import java.util.Iterator;
import java.util.List;
import models.Ball;
public class MainLoop extends Thread {
@Override
public void run() {
List<Ball> balls;
new Ball(5,5,2,2,10,15);
while (true){
balls = Ball.all().fetch(); //Here throws an exception
for (Iterator iterator = balls.iterator(); iterator.hasNext();) {
Ball ball = (Ball) iterator.next();
ball.applyForces();
}
}
}
}
有任何想法吗?
不要使用纯线程,而是使用job:
@OnApplicationStart
public class MainLoop extends Job {
public void doJob() {
new BallJob().now();
}
}
和BallJob:
public class BallJob extends Job {
public void doJob() {
List<Ball> balls;
new Ball(5,5,2,2,10,15);
while (true){
balls = Ball.all().fetch();
for (Iterator iterator = balls.iterator(); iterator.hasNext();) {
Ball ball = (Ball) iterator.next();
ball.applyForces();
}
}
}
更新
这比下面的内容更整洁:
JPAPlugin.startTx(false);
// Do your stuff
JPAPlugin.endTx(false);
今天有类似的问题。
您必须为每个线程创建新的EntityManager
和事务,并在JPA类中设置它。
Play使用ThreadLocal
将它的EntityManager
在JPA中 ,因此对于您创建的线程它是null。 遗憾的是,您无法在JPA中使用帮助程序方法(它们是包私有),您必须直接使用ThreadLocal
。 这是你如何做到这一点:
class Runner extends Runnable {
@Override
public void run() {
if (JPA.local.get() == null) {
EntityManager em = JPA.newEntityManager();
final JPA jpa = new JPA();
jpa.entityManager = em;
JPA.local.set(jpa);
}
JPA.em().getTransaction().begin();
... DO YOUR STUFF HERE ...
JPA.em().getTransaction().commit();
}
}
我使用java.util.concurrent中的单线程执行器没有任何问题。
我猜你的线程在Play有机会启动JPA实体经理之前就开始了。
如果您的Model类使用@Entity注释,那么将创建实体管理器并且不会出现您的错误。
所以,你有几个选择。 要么,
就个人而言,我会选择选项2.更好的文档记录,播放插件更多的是扩展框架而不是改变处理顺序。
class Runner extends Runnable {
@Override
public void run() {
EntityManager em = JPA.newEntityManager();
em.setFlushMode(FlushModeType.COMMIT);
JPA jpa = new JPA();
jpa.bindForCurrentThread(JPA.DEFAULT, em, false);
em.getTransaction().begin();
// ... DO YOUR STUFF HERE ...
em.getTransaction().commit();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.