Я пытаюсь добавить записи в базу данных через вызов WebSocket в java EE, все еще изучая это (я определенно не понимаю все концепции). Я получаю следующие две ошибки в зависимости от того, как я настроить мой код:Как сохранить сущность в java EE?
Ошибка № 1: java.lang.IllegalStateException: Исключение Описание: Не удается использовать EntityTransaction при использовании JTA.
Ошибка № 2: javax.persistence.TransactionRequiredException
Излишне говорить, что я ничего не получаю в моей БД. Вероятно, в моем коде и общем дизайне есть куча вещей, которые менее оптимальны, любые советы или указатели приветствуются, но вопрос в том, куда я могу перейти отсюда, чтобы получить моего пользователя в базу данных?
Я работаю со следующей простой настройкой, чтобы получить что-то работающее, прежде чем решать всю проблему.
Мой Entity:
@Entity
@Table(name = "USER_TABLE")
public class User implements Serializable {
@Id
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Мой объект доступа к данным, в конце концов, это где магия DB вещи для пользователя должно произойти:
public class UserDAO {
private EntityManager mEM;
public void save(User user) {
//mEM.getTransaction().begin(); // with comment = error no 2 | no comment = no 1
mEM.persist(user); // I was thinking that this was the magic I needed.
//mEM.getTransaction().commit(); // with comment = error no 2 | no comment = no 1
}
public void setEM(EntityManager em) {
mEM = em;
}
}
У меня также есть DatabaseIO, мое мышление что если у меня есть нечто большее, чем просто субъект пользователя, я бы хотел собрать всю базу данных IO в одном классе:
public class DatabaseIO {
private EntityManager mEM;
public DatabaseIO(EntityManager em) {
System.out.println("DatabaseIO(" + em + ")");
mEM = em;
}
public void createUser(String name) {
System.out.println("createUser(" + name + ")");
User user = new User();
user.setName(name);
UserDAO userDAO = new UserDAO();
userDAO.setEM(mEM);
userDAO.save(user);
}
}
Затем у меня есть несколько классов, которые будут использовать IO базы данных и обрабатывать запросы, поступающие в приложение. В основном бизнес-логика. Я не назвал это как bean-компонент, поскольку они созданы с каждым пользователем, подключающимся к приложению. И как только они будут подключены, пользователю1 может потребоваться доступ к объекту SomeClass пользователя2, не был уверен, как это сделать, не создавая объекты, а не контейнер.
public class SomeClass {
private DatabaseIO mDbIO;
public SomeClass(EntityManager em) {
mDbIO = new DatabaseIO(em);
}
public void newUser(String name) {
mDbIO.createUser(name);
}
}
У меня есть EJB, который начинается с приложением и имеет определенный статус для всех приложений, но не уверен, что это лучший (скорее всего, есть лучшие способы, моя цель состояла в том, чтобы не ставить, что мне нужно часто в базе данных, пока я не закончил с ним) путь, но это то, что я придумал до сих пор:
@Startup
@Singleton
@Named("some_manager")
public class SomeApplicationManager {
@PersistenceContext(unitName="AddUsersPU")
private EntityManager mEM;
public EntityManager getEM() {
return mEM;
}
}
И, наконец, моя WebSocket конечная точка:
@ServerEndpoint("/WebSocket")
public class WebEndpoint {
@Inject
SomeApplicationManager mAppManager;
@OnOpen
public void onOpen(Session aSession, EndpointConfig aConfig) {
aSession.addMessageHandler(new MessageHandler.Whole<String>() {
@Override
public void onMessage(String aUserName) {
System.out.println("new user: " + aUserName);
SomeClass aClassObj = new SomeClass(mAppManager.getEM());
aClassObj.newUser(aUserName);
}
});
}
}
Я проверил это с просто JavaScript, и я получаю ввод, который я ожидаю, пока строки в UserDAO, где я прокомментировал, что я получаю сообщение об ошибке.
EDIT: Из того, что я понимаю, из приведенных ниже ответов и некоторых других поисковых запросов причина, по которой mEM.persist (пользователь) не работает, заключается в том, что контейнер не управляется им. Я попытался исправить это, аннотируя UserDAO как @Stateless и введя его через @EJB в DatabaseIO, как было предложено. Однако это дало мне исключение NullPointerException. Затем я также обозначил DatabaseIO и SomeClass как @Stateless и вместо явного создания SomeClass в WebEndpoint (и DatabaseIO в SomeClass) я ввел его с помощью @EJB. На данный момент я фактически получил объект в базе данных, но я не уверен, что все это понимаю.
Я сделал что-то похожее на это, и это сработало для меня. Пожалуйста, посмотрите –