Recently, I've decided to use EJB in my project. Basically, are Stateless EJBs in order to make the business layer and persist data. I'm also using container managed transactions (CMT) and everything works fine.
I tried to handle the exceptions in EJB service methods in order to get the more specific exceptions and give specific errors messages to the client.
@Stateless
public class EJBService {
@PersistenceContext(unitName="PU")
private EntityManager em;
public void save(Animal a) throws AppException
{
try
{
em.persist(e);
}
catch(ConstraintViolationException ex)
{
throw new AppException("message");
}
catch(Exception ex)
{
throw new AppException("message 1");
}
}
}
The AppException extends Exception and is marked with the annotation @ApplicationException(rollback=true)
However, I can't handle the exception before the method commit the transaction. If something goes wrong the transactions are not commited (OK), but I don't have the specific exception, only javax.ejb.EJBTransactionRolledbackException: Transaction rolled back. I could use the flush method after try to persist or merge, but it isn't seems right.
So, I've decided don't try to handle the exceptions in EJB service layer leaving my methods like this:
@Stateless
public class EJBService {
@PersistenceContext(unitName="PU")
private EntityManager em;
public void save(Animal a)
{
em.persist(a);
}
and the client (A managed bean, for example), like this:
@Named
@RequestScoped
public class Bean {
private Animal animal;
@Inject
private EJBService service;
public void save() {
try
{
service.save(animal);
}
catch(Exception e)
{
//Unwrapping the exception in order to pass the
//appropriate message
}
}
}
In order to show the right messages, the method who invoked the ejb service must to handle the exception by itself, unwrapping the exception.
The question is: Am I right ? If I'm not, what is the best way to handle exceptions ?