对象持久性不起作用
Object persistence doesn't work
我正在尝试使用 JPA 进行一些聊天。除了一件事,一切都有效。我想,当我的用户打开与端点的连接时,保存他的房间号、他的昵称和时间戳。
我的 table 已创建得很好,列也已创建,但我无法在数据库中保留我的 Connexion 对象。
我正在使用 Glasfish 4.0,我已经创建了我的 JDBC资源和 JDBC 连接池,它们运行良好。
这是我的ChatEndPoint.Java
package server;
import java.io.IOException;
import javax.websocket.EncodeException;
import javax.websocket.EndpointConfig;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
// traitement de la connexion d'un client
@OnOpen
public void open(Session session, EndpointConfig conf, @PathParam("room-name") String roomName, @PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
DAO dao=new DAO();
dao.createConnection(nickName, roomName);
}
// traitement de la reception d'un message client
@OnMessage
public void onMessage(Session session, ChatMessage msg) throws IOException,
EncodeException {
if (msg instanceof ChatMessage) {
ChatMessage reponse = new ChatMessage(msg.getEmetteur(),
msg.getSalle(), msg.getMessage());
for (Session sess : session.getOpenSessions()) {
if (sess.isOpen()
&& sess.getUserProperties().get("salle")
.equals(msg.getSalle()))
sess.getBasicRemote().sendObject(reponse);
}
}
}
}
My Connexion class who represent my entity to save :
Connexion.java
package server;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
@Entity
public class Connexion implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column( name = "nickName" )
protected String nickName;
@NotNull
@Column( name = "roomName" )
protected String roomName;
@Column( name = "dateConnexion" )
protected Timestamp connectionDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
public Timestamp getConnectionDate() {
return connectionDate;
}
public void setConnectionDate(Timestamp timestamp) {
this.connectionDate = timestamp;
}
}
DAO.java
package server;
import java.sql.Timestamp;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
@Stateless
@LocalBean
public class DAO {
@PersistenceUnit
private EntityManagerFactory emf;
// Injection du manager, qui s'occupe de la connexion avec la BDD
@PersistenceContext(unitName="projetwebee1")
EntityManager em;
// Enregistrement d'un nouvel utilisateur
public void createConnection(String nickName, String roomName) throws Exception{
this.emf=Persistence.createEntityManagerFactory("projetwebee1");
this.em = this.emf.createEntityManager();
Connexion c = new Connexion();
c.setNickName(nickName);
c.setRoomName(roomName);
c.setConnectionDate(new Timestamp((new java.util.Date()).getTime()));
System.out.println(" "+em);
em.persist(c);
System.out.println("persist OK");
}
}
persistence.xml generated by JPA. But i edited some part of it
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="projetwebee1" transaction-type="JTA">
<jta-data-source>JEEProjectJNDIFinal3</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables" />
</properties>
</persistence-unit>
</persistence>
因此,在我尝试保留我的实体后,我无法在我的数据资源管理器中看到它。除了我在官方文档甚至此处找到的方法之外,我已经尝试了很多其他方法。但是没有人成功。
感谢您的帮助
EJB 容器在您的 bean 中注入一个实体管理器,但您丢弃它并用您自己创建的实体管理器替换它。你只需要
@Stateless
@LocalBean
public class DAO {
@PersistenceContext
EntityManager em;
public void createConnection(String nickName, String roomName) {
Connexion c = new Connexion();
c.setNickName(nickName);
c.setRoomName(roomName);
c.setConnectionDate(new Timestamp((new java.util.Date()).getTime()));
em.persist(c);
}
但问题在于,您不是让容器创建此 EJB,而是您自己实例化它,将应该是可注入的事务性 EJB 转换为非 EJB 容器管理的哑对象。永远不要使用 new 来获取 EJB 的实例。使用依赖注入。
而不是
@ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
// traitement de la connexion d'un client
@OnOpen
public void open(Session session, EndpointConfig conf, @PathParam("room-name") String roomName, @PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
DAO dao=new DAO();
dao.createConnection(nickName, roomName);
使用
@ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
@Inject
private DAO dao;
// traitement de la connexion d'un client
@OnOpen
public void open(Session session, EndpointConfig conf, @PathParam("room-name") String roomName, @PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
dao.createConnection(nickName, roomName);
我正在尝试使用 JPA 进行一些聊天。除了一件事,一切都有效。我想,当我的用户打开与端点的连接时,保存他的房间号、他的昵称和时间戳。 我的 table 已创建得很好,列也已创建,但我无法在数据库中保留我的 Connexion 对象。
我正在使用 Glasfish 4.0,我已经创建了我的 JDBC资源和 JDBC 连接池,它们运行良好。
这是我的ChatEndPoint.Java
package server;
import java.io.IOException;
import javax.websocket.EncodeException;
import javax.websocket.EndpointConfig;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
// traitement de la connexion d'un client
@OnOpen
public void open(Session session, EndpointConfig conf, @PathParam("room-name") String roomName, @PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
DAO dao=new DAO();
dao.createConnection(nickName, roomName);
}
// traitement de la reception d'un message client
@OnMessage
public void onMessage(Session session, ChatMessage msg) throws IOException,
EncodeException {
if (msg instanceof ChatMessage) {
ChatMessage reponse = new ChatMessage(msg.getEmetteur(),
msg.getSalle(), msg.getMessage());
for (Session sess : session.getOpenSessions()) {
if (sess.isOpen()
&& sess.getUserProperties().get("salle")
.equals(msg.getSalle()))
sess.getBasicRemote().sendObject(reponse);
}
}
}
}
My Connexion class who represent my entity to save :
Connexion.java
package server;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
@Entity
public class Connexion implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column( name = "nickName" )
protected String nickName;
@NotNull
@Column( name = "roomName" )
protected String roomName;
@Column( name = "dateConnexion" )
protected Timestamp connectionDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
public Timestamp getConnectionDate() {
return connectionDate;
}
public void setConnectionDate(Timestamp timestamp) {
this.connectionDate = timestamp;
}
}
DAO.java
package server;
import java.sql.Timestamp;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
@Stateless
@LocalBean
public class DAO {
@PersistenceUnit
private EntityManagerFactory emf;
// Injection du manager, qui s'occupe de la connexion avec la BDD
@PersistenceContext(unitName="projetwebee1")
EntityManager em;
// Enregistrement d'un nouvel utilisateur
public void createConnection(String nickName, String roomName) throws Exception{
this.emf=Persistence.createEntityManagerFactory("projetwebee1");
this.em = this.emf.createEntityManager();
Connexion c = new Connexion();
c.setNickName(nickName);
c.setRoomName(roomName);
c.setConnectionDate(new Timestamp((new java.util.Date()).getTime()));
System.out.println(" "+em);
em.persist(c);
System.out.println("persist OK");
}
}
persistence.xml generated by JPA. But i edited some part of it
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="projetwebee1" transaction-type="JTA">
<jta-data-source>JEEProjectJNDIFinal3</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables" />
</properties>
</persistence-unit>
</persistence>
因此,在我尝试保留我的实体后,我无法在我的数据资源管理器中看到它。除了我在官方文档甚至此处找到的方法之外,我已经尝试了很多其他方法。但是没有人成功。
感谢您的帮助
EJB 容器在您的 bean 中注入一个实体管理器,但您丢弃它并用您自己创建的实体管理器替换它。你只需要
@Stateless
@LocalBean
public class DAO {
@PersistenceContext
EntityManager em;
public void createConnection(String nickName, String roomName) {
Connexion c = new Connexion();
c.setNickName(nickName);
c.setRoomName(roomName);
c.setConnectionDate(new Timestamp((new java.util.Date()).getTime()));
em.persist(c);
}
但问题在于,您不是让容器创建此 EJB,而是您自己实例化它,将应该是可注入的事务性 EJB 转换为非 EJB 容器管理的哑对象。永远不要使用 new 来获取 EJB 的实例。使用依赖注入。
而不是
@ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
// traitement de la connexion d'un client
@OnOpen
public void open(Session session, EndpointConfig conf, @PathParam("room-name") String roomName, @PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
DAO dao=new DAO();
dao.createConnection(nickName, roomName);
使用
@ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
@Inject
private DAO dao;
// traitement de la connexion d'un client
@OnOpen
public void open(Session session, EndpointConfig conf, @PathParam("room-name") String roomName, @PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
dao.createConnection(nickName, roomName);