MiK*_*Kom 4 java rest jpa jax-rs
我在我的应用程序中使用jax-rs restful web服务和子资源定位器.但是,在将entityManager传递给子资源后,我无法在此子资源中保留任何新对象.
然而,entityManager让我可以查询数据.
这是我的主要资源:
@Path("/registrations")
@Stateless
public class RegistrationsResource {
@Context
private UriInfo context;
@PersistenceContext(unitName="pctx")
private EntityManager em;
public RegistrationsResource() {
}
//POST method ommited
@Path("{regKey}")
public RegistrationResource getRegistrationResource(@PathParam("regKey")
String regKey) {
return RegistrationResource.getInstance(regKey, em);
}
Run Code Online (Sandbox Code Playgroud)
}
这是我的子资源:
public class RegistrationResource {
private String regKey;
private EntityManager em;
private RegistrationResource(String regKey, EntityManager em) {
this.regKey = regKey;
this.em = em;
}
@Path("securityQuestion")
@GET
public String getQuestion() {
return "iamahuman"+regKey;
}
@Path("securityQuestion")
@POST
public void postSecurityAnswer(String answer) {
if(!answer.equals("iamahuman"+regKey)){
throw new WebApplicationException(Status.BAD_REQUEST);
}
//Getting this information works properly
List<RegistrationEntity> result = em.createNamedQuery("getRegistrationByKey")
.setParameter("regKey", regKey).getResultList();
switch(result.size()){
case 0 :
throw new WebApplicationException(Status.NOT_FOUND);
case 1:
break;
default:
throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
}
RegistrationEntity reg = result.get(0);
UserEntity newUser = new UserEntity();
newUser.setHashedPassword(reg.getPwHash(), reg.getSalt());
newUser.setUsername(reg.getUsername());
newUser.setName(reg.getName());
newUser.setSurname(reg.getSurname());
//CRASHES HERE
em.persist(newUser);
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它从数据库中获取注册对象,创建新用户进行注册并尝试保留它.但是,em.persist(newUser)抛出TransactionRequiredException.
我的问题是:我应该如何将EntityManager传递给子资源,以便它能够正确地保留新对象?
很抱歉再次挖掘它,但我建议如下:
@EJB private RegistrationResource registrationResource;
public RegistrationResource getRegistrationResource() {
return this.registrationResource;
}但是,要使其工作,您不能将"@PathParam"作为构造函数参数传递.您必须通过"@Context"或其他@Path声明在子资源中单独访问它.
这使您能够以与父资源完全相同的方式在子资源中注入EntityManager,您无需将其传递.
可能为时已晚,但无论如何......当您返回子资源时,您“离开”了无状态 bean。当容器管理事务时,当您从 RegistrationsResource 返回时,事务就会被提交。
Jersey 然后将构建您的子资源,但它不是无状态 bean,因此您不会有容器管理的事务。因此例外。
我建议您将业务逻辑放入一个新类中,然后将其制作为无状态 bean。在这里,您可以完成所有数据库工作,然后这些工作始终在容器管理的事务中处理。
| 归档时间: |
|
| 查看次数: |
4482 次 |
| 最近记录: |