ejb@glassfish.java.net

EJB 3 and JPA Exception Handling

From: Butash, Bob <bob.butash_at_eds.com>
Date: Mon, 2 Oct 2006 12:47:23 -0400

All,

I have a question regarding Exception Handling regarding JPA code.

Here is my Scenario:

I have a JSF backing bean that is invoking a business service via a JNDI
lookup through the service locator pattern.
        public String registerNewUser() throws SystemUserException,
Exception
        {
            SystemUser user = (SystemUser)getManagedBeanValue("user")
            obtainSystemUserService().addSystemUser(user);
            user.setPassword(null);

            UserState userState =
(UserState)getManagedBeanValue("userState");
            userState.setUser(retrieveSystemUser());
            userState.setLoggedIn(true);
            return "success";
        }
I have a Local Stateless Session Bean that is acting as a Business
Service. The saveObject method is annotated to require a transaction.
It delegates to another Local Stateless Session bean that is acting as
the DAO. It merely throws any application exceptions that are thrown
from the DAO.
        @TransactionAttribute(TransactionAttributeType.SUPPORTED)
        public Object addSystemUser(SystemUser user) throws
SystemUserServiceException
        {
            return getSystemUserDAO().persistEntity(user);
        }


The Local DAO Stateless Session Bean's method annotated to require a
transaction. This method is invoking the EntityManager to perform the
persist. The call to the persist is surrounded with a try catch to
attempt to catch an exception during the persist and wrap it in an
Application exception.

        @TransactionAttribute(TransactionAttributeType.REQUIRED)
        public SystemUser persistEntity(SystemUser entity)
        {
            try
            {
                return (SystemUser)super.persistEntity(entity);
            }
            catch(Exception e)
            {
                throw new SystemUserException("Duplicate user");
            }
        }


However, if there is an error the catch is not hit and no exception
processing is encountered until the stack is back at the POJO JSF
backing bean and at that point I am catching an EJBException. I have
tried placing try catches at the Business Service Tier as well as I have
an EJB interceptor that is wrapping the call to the context.proceed with
a try/catch. The only time I can actually catch the EJBException is
when I'm out of the transactional processing, which is the POJO backing
bean. I have noticed if I change the transactional control on the
Business Service method to be NOT_SUPPORTED I can catch the exception at
that point, but that means if this was part of a more complex
tranasaction all of my transactional control would be lost.

Is there a way to catch Exceptions thrown from the
EntityManager.persist() and wrap them in a meaningful
ApplicationException?

Thanks for your assistance

Bob Butash