播放2.5.x - 没有绑定到此线程的EntityManager

时间:2017-03-23 12:21:23

标签: java jpa playframework-2.0 akka

我正在从Play 2.3.x迁移到2.5.x,我遇到了从akka actor访问数据库的问题。我在应用程序启动期间将调度程序注入EagerSingleton,并从那里创建访问数据库的调度。

Actor在构造函数中接收JPAAPI来访问数据库但每次尝试访问数据库时都会收到以下错误。

有没有人解决这个问题?

我是否还应该注入HTTP上下文?我怎么能这样做?

  

2017-03-23 11:46:16.990 +0000 - DashboardMonitor.onReceive:73 - 检查状态

     

java.lang.RuntimeException:JPA事务失败

     

at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:198)     在actors.DashboardMonitor.onReceive(DashboardMonitor.java:77)     at akka.actor.UntypedActor $$ anonfun $ receive $ 1.applyOrElse(UntypedActor.scala:165)     at akka.actor.Actor $ class.aroundReceive(Actor.scala:484)     at akka.actor.UntypedActor.aroundReceive(UntypedActor.scala:95)     at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526)     at akka.actor.ActorCell.invoke(ActorCell.scala:495)     at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)     at akka.dispatch.Mailbox.run(Mailbox.scala:224)     at akka.dispatch.Mailbox.exec(Mailbox.scala:234)     在scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)     在scala.concurrent.forkjoin.ForkJoinPool $ WorkQueue.runTask(ForkJoinPool.java:1339)     在scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)     在scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

     

引起:java.lang.RuntimeException:没有绑定到此线程的EntityManager。尝试在JPAApi.withTransaction中包装此调用,或确保在此线程上设置HTTP上下文。

     

at play.db.jpa.JPAEntityManagerContext.em(JPAEntityManagerContext.java:36)     at play.db.jpa.JPA.em(JPA.java:75)     在models.Probe.getAllProbes(Probe.java:270)     at utils.Utils.updatePlatformStatus(Utils.java:524)     在actors.DashboardMonitor.lambda $ onReceive $ 0(DashboardMonitor.java:78)     at play.db.jpa.DefaultJPAApi.lambda $ withTransaction $ 2(DefaultJPAApi.java:194)     at play.db.jpa.DefaultJPAApi.lambda $ withTransaction $ 3(DefaultJPAApi.java:211)     at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:152)     at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:210)     at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:193)   ......还有13个

这是我使用的代码:

@Singleton
public class DashboardMonitor extends UntypedActor {


    private final JPAApi jpaApi;

    @Inject
    public DashboardMonitor(JPAApi jpaApi) {

        this.jpaApi = jpaApi;

    }

    @Override
    public void onReceive(Object message) throws Exception {

        // check message type
        if (message.equals("updateStatus")) {

            try {

                jpaApi.withTransaction(() -> {
                    Utils.updatePlatformStatus();
                });


            }catch (Exception e){
                e.printStackTrace();
            }

        }

    }
}

调度程序:

@Singleton
public class DashboardScheduler {

    // Start aggregate session for aggregate probe
    private Cancellable updateStatusSchedule = null;

    @Inject
    public DashboardScheduler(ApplicationLifecycle lifeCycle, ActorSystem system, @Named("dashboard-monitor") ActorRef dashboardActor) {

        startUpdateStatus(system, dashboardActor);
        initStopHook(lifeCycle);

    }

    /**
     * Start probesTimedOutScheduler
     */
    private void startUpdateStatus(ActorSystem system, ActorRef dashboardActor) {

        if (updateStatusSchedule == null || updateStatusSchedule.isCancelled()) {

            updateStatusSchedule = system.scheduler().schedule(
                    Duration.create(10, TimeUnit.SECONDS),
                    Duration.create((GlobalConfiguration.probeUpdateInterval), TimeUnit.SECONDS),
                    dashboardActor,
                    "updateStatus",
                    system.dispatcher(),
                    null);

        }

    }

}

注射模块:

public class GlobalBootstrapModule extends AbstractModule implements    AkkaGuiceSupport {

    @Override
    protected void configure() {

        bindActor(DashboardMonitor.class, "dashboard-monitor");
        bind(DashboardScheduler.class).asEagerSingleton();

    }
}

0 个答案:

没有答案