I don't know why I can't catch the NoResultException thrown by a method in an EJB...
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());
}
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;
}
...
Why this code catches EJBException instead of NoResultException and how can I catch the NoResultException?
Avvertenza: javax.ejb.EJBException
...
...
Caused by: javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
Only application exceptions are reported to the client directly, i.e. without being wrapped in an EJBException
(note: in case of container-managed transaction demarcation, the client sees a EJBTransactionRolledbackException
instead).
The NoResultException
however is a system exception, meaning the EJB container will wrap that exception in an EJBException
.
Apply the @ApplicationException
annotation to an exception to make it an application exception. In this case you probably want to wrap the NoResultException
in your own NoSuchEmailException
(or the like) carrying the said annotation.
The EJB specification reads as follows...
A system exception is an exception that is a java.rmi.RemoteException (or one of its sub-classes) or a RuntimeException that is not an application exception.
An application exception is an exception defined by the Bean Provider as part of the business logic of an application. Application exceptions are distinguished from system exceptions in this specification.
And now the important part:
An application exception thrown by an enterprise bean instance should be reported to the client precisely (i.e., the client gets the same exception)
The specification goes on with clarifying the role and use of application exceptions:
Enterprise bean business methods use application exceptions to inform the client of abnormal application-level conditions, such as unacceptable values of the input arguments to a business method. A client can typically recover from an application exception.
An application exception may be a subclass (direct or indirect) of java.lang.Exception (i.e., a “checked exception”), or an application exception class may be defined as a subclass of the java.lang.RuntimeException. (an “unchecked exception”).