Mar*_*rco 1 jsf ejb exception-handling jakarta-ee
我不知道为什么我无法捕获 EJB 中的方法抛出的 NoResultException ......
try {
User user = userFacade.findByEmail(email);
userController.setSelected(user);
getSelected().setUserOid(user.getOid());
} catch (NoResultException noResultException) {
JsfUtil.addErrorMessage("No user found with provided email");
System.err.println(noResultException.getMessage());
} catch (EJBException e){
System.err.println(e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)
EJB
@Stateless
public class UserFacade extends AbstractFacade<User> {
...
public User findByEmail (String email) throws NoResultException{
User user = em.createNamedQuery("User.findByEmail", User.class).
setParameter("email", email).getSingleResult();
return user;
}
...
Run Code Online (Sandbox Code Playgroud)
为什么这段代码会捕获 EJBException 而不是 NoResultException 以及如何捕获 NoResultException?
Avvertenza: javax.ejb.EJBException
...
...
Caused by: javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
Run Code Online (Sandbox Code Playgroud)
只有应用程序异常直接报告给客户端,即没有被包装在一个EJBException(注意:在容器管理的事务划分的情况下,客户端看到的是一个EJBTransactionRolledbackException)。
该NoResultException然是一个系统异常,这意味着EJB容器将包装该异常在EJBException。
将@ApplicationException注释应用于异常以使其成为应用程序异常。在这种情况下,您可能希望将 包装NoResultException在您自己的NoSuchEmailException(或类似的)中,并带有所述注释。
EJB 规范如下...
系统异常是属于 java.rmi.RemoteException(或其子类之一)的异常或不是应用程序异常的 RuntimeException。
应用程序异常是由 Bean Provider 定义为应用程序业务逻辑一部分的异常。在本规范中,应用程序异常与系统异常是有区别的。
现在是重要的部分:
企业bean实例抛出的应用异常应该准确上报给客户端(即客户端得到同样的异常)
该规范继续阐明应用程序异常的作用和用途:
Enterprise bean 业务方法使用应用程序异常来通知客户端应用程序级别的异常情况,例如业务方法的输入参数的不可接受的值。客户端通常可以从应用程序异常中恢复。
应用程序异常可以是java.lang.Exception 的子类(直接或间接)(即“检查异常”),或者应用程序异常类可以定义为java.lang.RuntimeException 的子类。(“未经检查的异常”)。