我正在构建一个java REST应用程序。因此我在wildfly 8服务器上使用jboss。
以下代码会导致此异常:JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
@Path("/users")
@Stateless
public class UsersEndpoint {
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response create(User user) {
try {
this.checkUsername(user.getUsername());
this.checkEmail(user.getEmail());
return Response.ok(userDAO.create(user)).build();;
} catch (IOException e) {
return Response.status(Response.Status.NOT_ACCEPTABLE)
.entity(e.getMessage())
.build();
} catch (Exception e) {
return Response.status(Response.Status.NOT_ACCEPTABLE)
.entity(e.getMessage())
.build();
}
}
@POST
@Path("username")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.TEXT_HTML)
public Response username(String username) {
try {
this.checkUsername(username);
return Response.ok().build();
} catch (Exception e) {
return Response.status(Response.Status.NOT_ACCEPTABLE)
.entity(entity)
.build();
}
}
@POST
@Path("email")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.TEXT_HTML)
public Response email(String email) {
try {
this.checkEmail(email);
return Response.ok().build();
} catch (Exception e) {
return Response.status(Response.Status.NOT_ACCEPTABLE)
.entity(this.validator.validateError(null, e))
.build();
}
}
private void checkUsername(String username) throws IOException {
try {
userDAO.get(username);
throw new IOException("Username is taken allready.");
}
catch (IOException e) { throw e; }
catch (Exception e) { System.out.println("Username can be used"); }
}
private void checkEmail(String email) throws IOException {
try {
userDAO.getByEmail(email);
throw new IOException("Email is taken allready.");
}
catch (IOException e) { throw e; }
catch (Exception e) { System.out.println("Email can be used"); }
}
}
public Response email(String email)
和public Response username(String username)
功能正常运行。问题似乎是通过public Response create(User user)
函数调用这两个函数:
...
try {
this.checkUsername(user.getUsername());
this.checkEmail(user.getEmail());
...
所以,现在当我有一个正确的用户名但是重复的电子邮件时,JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
将会抛出异常userDAO.getByEmail(email)
。当我有一个重复的用户名时,IOException("Username is taken allready.")
将按预期抛出。
当我将这些功能的顺序更改为:
...
try {
this.checkEmail(user.getEmail());
this.checkUsername(user.getUsername());
...
同样的问题发生在userDAO.get(username)
并且使用正确的电子邮件和重复的用户名。
修改
当我在throw new IOException("Username is taken allready.");
中移除private void checkUsername(String username) throws IOException { }
时,第二个DAO调用正常。所以问题似乎是抛出的异常。我怎么解决这个问题?
我的UserDAO
public interface UserDAO {
public User create(User user) throws Exception;
public User get(String username) throws Exception;
public User getByEmail(String email) throws Exception;
}
我的UserBean
@Stateless
@Remote(UserDAO.class)
public class UserBean implements UserDAO {
// Injected database connection:
@PersistenceContext private EntityManager em;
@Override
public User create(User user) throws Exception {
em.persist(user);
return user;
}
@Override
public User get(String username) throws Exception {
return em.createNamedQuery(User.QUERY_USERNAME, User.class)
.setParameter("userName", username)
.getSingleResult();
}
@Override
public User getByEmail(String email) throws Exception {
return em.createNamedQuery(User.QUERY_EMAIL, User.class)
.setParameter("email", email)
.getSingleResult();
}
}