使用play Framework 2.5 for Java
我想创建一个使用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);
}
}
我曾尝试过注入JPaapi,以及更多不同的东西,但我几乎不熟悉Play Framework
答案 0 :(得分:1)
首先,在Play Framework中,我建议使用Akka actor而不是传统的Java Threads。一开始看起来似乎很复杂,但是一旦掌握它就会节省大量的调试时间。 Akka已经集成在Play中,所以它应该不是问题。
现在,关于您的实体经理。首先,确保在sbt构建文件中有java JDBC:libraryDependencies += javaJdbc
接下来,在您的配置文件中,确保您配置了默认DS:db.default.jndiName=DefaultDS
以及持久性单元(此处更多:https://www.playframework.com/documentation/2.5.x/JavaJPA)
现在,你的控制器(我在你发布的代码中看不到实际的控制器)必须有@Transactional
注释。