gpt4 book ai didi

java - Play Framework 2.5 在另一个线程中接收数据时没有 EntityManager 错误

转载 作者:行者123 更新时间:2023-12-01 09:13:07 24 4
gpt4 key购买 nike

使用 Java 的 play Framework 2.5

我想创建一个应用程序,它使用来自 ActiveMQ 的数据,并根据收到的消息对数据库执行一个 hibernate 查询并存储一个 User 对象。我简化了我的消费者类,以便在那里创建一个对象并同时调用持久性。

当我从接收测量的线程(或调用另一个类)调用持久性时,我的问题就出现了。然后 EntityManager 不存在,我无法创建一个新的,或者坦率地说,我不知道如何在 Play 中创建它。

package controllers;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

import models.User;
import play.Logger;
import play.db.jpa.JPA;

public class MessageConsumerController implements Runnable, ExceptionListener {
private static final String TOPIC_NAME = "miguelTopic";
private static Thread consumerService;

public static synchronized void initService() {
Logger.info("Message Consumer initialized");
MessageConsumerController MessageConsumer = new MessageConsumerController();
if (consumerService != null) {
Logger.info("STOPPING MessageConsumer thread.");
consumerService.interrupt();
}
Logger.info("Starting MessageConsumer thread.");
consumerService = new Thread(MessageConsumer);
consumerService.setDaemon(true);
consumerService.setName("MessageConsumer Service");
consumerService.start();
Logger.info("MessageConsumer thread started.");
}

@Override
public void run() {
try {

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("admin", "admin",
"tcp://localhost:61616");

Logger.info("Creating ActiveMQ connection");
Connection connection = connectionFactory.createConnection();
connection.start();
connection.setExceptionListener(this);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Logger.info("Connecting to topic " + TOPIC_NAME);
Destination destination = session.createTopic(TOPIC_NAME);

Logger.info("Creating consumer");
MessageConsumer consumer = session.createConsumer(destination);

while (!Thread.currentThread().isInterrupted()) {
Logger.info("Wait for messages...");
Message message = consumer.receive();

if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText();
Logger.info("Received: " + text);
User user = new User();
user.setId(555);
user.setName("miguel");
user.setTime_of_start("time");
Logger.info("insert user");

//JPAApi jpa = Play.current().injector().instanceOf(JPAApi.class);

JPA.em().getTransaction().begin();
JPA.em().persist(user); //
JPA.em().getTransaction().commit();



} else {
Logger.info("Received: " + message.getClass().getSimpleName());
}

}
Logger.info("Message consumer interrupted.");
consumer.close();
session.close();
connection.close();
} catch (Exception e) {
if (e instanceof InterruptedException) {
Logger.info("Message Consumer thread interrupted.");
} else {
Logger.error(e.getLocalizedMessage(), e);
}
}
}

public synchronized void onException(JMSException ex) {
Logger.error("JMS Exception occured. Shutting down client.");
Logger.error("ErrorCode=" + ex.getErrorCode() + " , " + ex.getMessage(), ex);
}

}

我尝试过注入(inject) JPaapi 以及许多其他不同的东西,但我对 Play Framework 几乎是新手

最佳答案

首先,在 Play Framework 中我建议使用 Akka actor 而不是传统的 java 线程。乍一看可能很复杂,但是一旦掌握了它的窍门,它将节省大量调试时间。 Akka 已经集成到 Play 中,所以这应该不是问题。

现在,关于您的实体管理器。首先,确保 sbt 构建文件中有 java JDBC:libraryDependency += javaJdbc

接下来,在配置文件中确保配置了默认 DS:db.default.jndiName=DefaultDS 以及持久性单元(更多信息:https://www.playframework.com/documentation/2.5.x/JavaJPA)

现在,您的 Controller (我在您发布的代码中没有看到实际的 Controller )必须具有 @Transactional 注释。

关于java - Play Framework 2.5 在另一个线程中接收数据时没有 EntityManager 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40792049/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com