Announcement Announcement Module
Collapse
No announcement yet.
No service Exception translation on EJBException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • No service Exception translation on EJBException

    Hi,

    I have a business interface with a method that throws two service exception (DataRetrievalFailureException and IllegalArgumentException):
    Code:
    public interface IServeiPersones
    {
        /**
         * Obté la persona associada amb l'identificador indicat.
         * @param idPersona identificador de la persona. Ha de ser igual o major de zero
         * @throws IllegalArgumentException Si l'identificador és menor de zero
         * @throws DataRetrievalFailureException Si no n'hi ha cap persona associada amb l'identificador indicat
         */
        public IPersona obtenirPersona(long idPersona);
    And a POJO implementation:
    Code:
        /* (non-Javadoc)
         * @see cat.base.bfp.serveis.IServeiPersones#obtenirPersona(long)
         */
        @Override
        public IPersona obtenirPersona(long idPersona)
        {
            HibernateTemplate ht;
            /*
             * Exemple de com combinar hibernate i SQL.
             * Aquí emprem hibernate, a la resta emprem jdbc
             */
            if(idPersona >= 0L)
            {
                IPersona p;
                
                ht = new HibernateTemplate(sessionFactory);
                p = (IPersona)ht.get(PersonaH.class, idPersona);
                if(p == null)
                {
                    throw new DataRetrievalFailureException("La persona amb identificador '" + idPersona + "' no existeix pas al registre");
                }
                return p;
            }
            throw new IllegalArgumentException("L'identificador '" + idPersona + "' no és pas correcte");
        }
    Then, I publish this service with an EJB:
    Code:
    @Stateless(name="ServeiPersonesEJB")
    @Interceptors(ServeiPersonesEJBConfigurator.class)
    @Remote(IServeiPersones.class)
    @Local(IServeiPersones.class)
    @Transactional(readOnly=true, propagation=Propagation.REQUIRED)
    @RemoteBinding(jndiBinding="bfp/ServeiPersones/remote")
    @LocalBinding(jndiBinding="bfp/ServeiPersones/local")
    public class ServeiPersonesEJB implements IServeiPersones
    {
        @Autowired(required=true)
        private IServeiPersones serveiPersones;
        /* (non-Javadoc)
         * @see cat.base.bfp.serveis.IServeiPersones#obtenirPersona(long)
         */
        @Override
        public IPersona obtenirPersona(long idPersona)
        {
            return serveiPersones.obtenirPersona(idPersona);
        }
    Finally I use that service from a WAR application (really more than one client in different war applications):

    Code:
    	<!-- Accés al servei -->
    	<jee:local-slsb id="serveiPersones"
    		jndi-name="bfp/ServeiPersones/local"
    		business-interface="cat.base.bfp.serveis.IServeiPersones">
    	</jee:local-slsb>
    And on the SWF controller:
    Code:
            try
            {
                pbb.setPersona(serveiPersones.obtenirPersona(pbb.getIdPersona()));
            }
            catch(DataRetrievalFailureException e)
            {
                logger.error("No n'hi ha cap persona amb l'identificador '" + pbb.getIdPersona() + "' indicat");
                pbb.getErrors().add("No n'hi ha cap persona amb l'identificador '" + pbb.getIdPersona() + "' indicat");
                
                return SORTIDA_ERROR;
            }
    But the controller doesn't catch the DataRetrievalFailureException because EJBException is thrown. I don't know how to get the service exception nor the EJB exception.

    Anybody can help me?
    Thanks

  • #2
    Hi,

    I found a solution. I make my own Proxy with specific treatment for EJBException:
    Code:
    public class ExceptionTranslatorLocalStatelessSessionProxyFactoryBean extends LocalStatelessSessionProxyFactoryBean
    {
        private static final Logger logger = LoggerFactory.getLogger(ExceptionTranslatorLocalStatelessSessionProxyFactoryBean.class);
        /* (non-Javadoc)
         * @see org.springframework.ejb.access.LocalSlsbInvokerInterceptor#invokeInContext(org.aopalliance.intercept.MethodInvocation)
         */
        @Override
        public Object invokeInContext(MethodInvocation invocation) throws Throwable
        {
            if(logger.isDebugEnabled())
            {
                logger.debug("Invocació del mètode '{}' a l'EJB '{}'", invocation.getMethod().getName(),getJndiName());
            }
            try
            {
                return super.invokeInContext(invocation);
            }
            catch(EJBException e)
            {
                logger.error("La invocació del mètode '{}' de l'EJB '{}' ha provocat una excepció EJB amb causa: '{}'"
                        ,new Object[] {invocation.getMethod().getName()
                        ,getJndiName()
                        ,e.getCause()});
    
                // Si n'hi ha, de causa...
                if(e.getCause() != null)
                {
                    // Llencem aquesta
                    throw e.getCause();
                }
                // Sinó, llencem l'EJB perquè no sabem com traduir-la
                throw e;
            }
            finally
            {
                if(logger.isDebugEnabled())
                {
                    logger.debug("FI de l'invocació del mètode '{}' a l'EJB '{}'", invocation.getMethod().getName(),getJndiName());
                }
            }
        }
    Then, on xml configuration:
    Code:
       <bean id="serveiPersones" class="cat.base.bfp.ui.ejb.ExceptionTranslatorLocalStatelessSessionProxyFactoryBean">
          <property name="businessInterface" value="cat.base.bfp.serveis.IServeiPersones"/>
          <property name="jndiName" value="bfp/ServeiPersones/local"/>
       </bean>
    They works like a charm.

    Thanks to all!

    Comment

    Working...
    X