【发布时间】:2018-06-04 21:16:19
【问题描述】:
我有一个名为 AuthenticationEndpoint 的 RESTful 服务,它检查用户的用户名/密码对、创建令牌、将令牌保存到数据库并将令牌返回给应用程序客户端。 代码工作没有错误和异常。 UserEJB bean 应该将令牌保存到 Token 数据库表中,而 AuthenticationEJB bean 应该更新 User 数据库表中的令牌字段。但正如我在 MySQL Workbench 中看到的,没有保存或更新任何内容。 UserEJB.getUsers() 方法工作正常并返回用户列表,似乎 EJB 容器找到了持久性单元 ForthDynamicWebProject,但为什么我不能保存和更新实体?感谢您的关注。
AuthenticationEndpoint RESTful 服务
@ApplicationScoped
@Path("/authentication")
public class AuthenticationEndpoint {
@Inject
AuthenticateEJB authenticateEJB;
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response authenticateUser(String jsonString) {
Gson gson = new Gson();
Credentials credentials = gson.fromJson(jsonString, Credentials.class);
String userName = credentials.getUserName();
String password = credentials.getPassword();
try {
User user = authenticateEJB.checkUser(userName, password);
if ((user instanceof User) && user != null) {
return Response.ok().header("token", user.getToken().getToken()).build();
} else {
return Response.status(Response.Status.FORBIDDEN).build();
}
} catch (Exception e) {
return Response.status(Response.Status.FORBIDDEN).build();
}
}
}
这是 EJB 的代码:
验证EJB
@LocalBean
@Stateless
public class AuthenticateEJB {
@PersistenceContext(unitName = "ForthDynamicWebProject")
EntityManager em;
@Inject
UserEJB userEJB;
public User checkUser(String userName, String password) {
List<User> users = userEJB.getUsers();
for (User user : users) {
if (user.getUsername().equals(userName) && user.getPassword().equals(password)) {
user.setToken(userEJB.updateToken());
em.merge(user);
return user;
}
}
return null;
}
}
用户EJB
@LocalBean
@Stateless
public class UserEJB {
@PersistenceContext(unitName = "ForthDynamicWebProject")
EntityManager em;
@Inject
Token token;
public List<User> getUsers() {
Query query = em.createQuery("from User");
return (List<User>) query.getResultList();
}
public Token updateToken() {
em.persist(token);
return token;
}
}
persistence.xml:
<?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="ForthDynamicWebProject" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/second_attempt_hibernate</jta-data-source>
<class>converters.ConverterLocalDateTime</class>
<class>entity.DocStatus</class>
<class>entity.DocType</class>
<class>entity.Document</class>
<class>entity.Employee</class>
<class>entity.MailOrder</class>
<class>entity.MailOrderStatus</class>
<class>entity.Token</class>
<class>entity.User</class>
</persistence-unit>
</persistence>
更新:
令牌实体
@Entity
@Table(name = "tokens")
@NamedQuery(name = "Token.findAll", query = "SELECT t FROM Token t")
public class Token implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Temporal(TemporalType.TIMESTAMP)
private Date loginTime;
private String token;
// bi-directional one-to-one association to User
@OneToOne(mappedBy = "token")
private User user;
public Token() {
ConverterLocalDateTime converter = new ConverterLocalDateTime();
loginTime = converter.convertToDatabaseColumn(LocalDateTime.now());
token = Double.toString(Math.random());
}
*getters and setters are not showed*
用户实体
@Entity
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String password;
private String username;
//bi-directional one-to-one association to Employee
@OneToOne(mappedBy="user")
private Employee employee;
//bi-directional one-to-one association to Token
@OneToOne
@JoinColumn(name="tokID")
private Token token;
public User() {
}
*getters and setters are not showed*
【问题讨论】:
-
首先,您应该始终使用从 merge() 返回的实体。其次,您为什么不创建一个查询来获取用户而不是遍历所有用户?第三,只要您不实现远程或本地接口,您就可以删除@LocalBean。但这不是问题所在。请告诉我们更多关于:什么是Token?它从何而来?用户可能已经分配了这个令牌吗?
-
@SimonMartinelli 我已经更新了这个问题。 User 和 Token 是实体,我是通过 Eclipse 中的 Tables 生成实体来获得的。
-
好的,但是注入的东西是从哪里来的?
-
@SimonMartinelli 我认为,容器在 UserEJB 中自行完成:'@Inject Token token;'
-
您如何(何时)检查数据库记录未被创建的事实?
em.persist()所做的只是将实体标记为持久的。这并不一定意味着持久化的实体会立即插入到数据库中。这通常发生在事务提交时。
标签: jpa transactions ejb