Mau*_*bon 10 multithreading jpa playframework
我正在尝试创建一个多线程服务器.问题是我收到以下错误: 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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
Ric*_*rdo 13
不要使用纯线程,而是使用job:
@OnApplicationStart
public class MainLoop extends Job {
public void doJob() {
new BallJob().now();
}
}
Run Code Online (Sandbox Code Playgroud)
和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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新
这比下面的更整洁:
JPAPlugin.startTx(false);
// Do your stuff
JPAPlugin.endTx(false);
Run Code Online (Sandbox Code Playgroud)
今天遇到了类似的问题。
您必须EntityManager为每个线程创建新的和事务并将其设置在JPA类中。
Play 用于ThreadLocal将其保留EntityManager在JPA 中,因此对于您创建的线程来说它为空。不幸的是,您不能在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();
}
}
Run Code Online (Sandbox Code Playgroud)
我将它与java.util.concurrent 中的单线程执行程序一起使用,没有任何问题。
| 归档时间: |
|
| 查看次数: |
5894 次 |
| 最近记录: |