5 Replies Latest reply on Nov 27, 2009 12:57 PM by nilon

    How do I handle exceptions thrown by the database?

    nilon

      I am using JBOSS AS 5.1.0 and Seam 2.2.0 , both GA versions. I use interceptors to demarcate transactions.




          @AroundInvoke
          public Object runProcess(InvocationContext p_ivc) throws Exception
          {
              Object result = null;
              userTransaction = context.getUserTransaction();
      
              try
              {
                  beginTransaction();
                  result = p_ivc.proceed();
                  commitTransaction();
              }
              catch (Exception e)
              {
                  rollbackTransaction();
                  . . .
              }
              return result;
      
          }
      



      I need to catch exceptions as javax.persistence.PersistenceException. The only exception that is returned when an exception occurs in the database is RollbackException.
      When I used the JBoss 4.3.0 with Seam 2.1.2 does not happen and I could treat various types of exceptions. My components are EJBs Stateless ( @TransactionManagement(TransactionManagementType.BEAN) )


      @Stateless
          @TransactionManagement(TransactionManagementType.BEAN)
          @Name("ejbComponent")
          @Scope(ScopeType.STATELESS)
          public class EjbComponent implements IEjbComponent
          {
              . . .
      



      In my front-end I am using Adobe Flex. The integration with Seam is the Flamingo.
          In the file components.xml I have the following lines:



      <core:init  ... transaction-management-enabled="false"/>
        <transaction:ejb-transaction/>
             . . .



      Thanks for any help!






        • 1. Re: How do I handle exceptions thrown by the database?
          asookazian

          Why are you using BMT rather than CMT?  As far as the change in exceptions from AS 4.x to AS 5.x, that seems strange.  Did you change JPA persistence providers or db?

          • 2. Re: How do I handle exceptions thrown by the database?
            nilon

            The database and the JPA persistence has not changed.
            I have many rules of business in the database and must catch the exceptions to translate them to the client.
            When I use CMT can not catch these exceptions. I try to use the annotation @Observer({org.jboss.seam.exceptionNotHandled,org.jboss.seam.exceptionHandled})
            but the annotated method is never called. The solution to this problem was to use BMT.

            • 3. Re: How do I handle exceptions thrown by the database?
              asookazian

              Well then perhaps you have a valid concern for your scenario if you can not refactor the business rules out of your db objects.  Although I'm not sure how popular or recommended it is to embed business rules in the db objects unless they're legacy code.



              An application exception signals an error in the business logic of an enterprise bean. Application exceptions are typically exceptions that you’ve coded yourself, such as the BookException thrown by the business methods of the CartBean example. When an enterprise bean throws an application exception, the container does not wrap it in another exception. The client should be able to handle any application exception it receives.

              If a system exception occurs within a transaction, the EJB container rolls back the transaction. However, if an application exception is thrown within a transaction, the container does not roll back the transaction.

              http://java.sun.com/javaee/5/docs/tutorial/doc/bnbpj.html


              If you could refactor the business rules into EJB components and use @ApplicationException on custom application exceptions, then it may be a better solution and not require BMT.


              http://www.163jsp.com/help/javaee50api/javax/ejb/ApplicationException.html


              Honestly I have not seen too much coverage of using BMT with EJB 3 components in a Seam app in the ref doc or any Seam books.

              • 4. Re: How do I handle exceptions thrown by the database?
                nilon

                I have no choice with regard to the rules of business in the database. I can not reimplemented the rules in EJB components for many reasons.
                I could obtain information from the database if you could browse the stack of exceptions. I navigate in the stack of exceptions using the getCause(). The method getCause() returns a Throwable. In the instance of Throwable the getCause() returns null.
                In JBoss 4.2.3.GA I get javax.persistence.PersistenceException by browsing method getCause().

                • 5. Re: How do I handle exceptions thrown by the database?
                  nilon

                  I found a solution. I changed the type of transaction for CMT. So I created an interceptor to catch exceptions from the database.


                    Implementation interceptor:




                  @AroundInvoke
                      public Object myAroundInvoke(InvocationContext p_ivc) throws Exception
                      {
                          Object result = null;
                  
                          try
                          {
                              result = p_ivc.proceed();
                  
                          }
                          catch (Exception e)
                          {
                  
                              if (e instanceof EJBTransactionRolledbackException)
                              {
                                   ...
                  
                              }
                  
                          }
                          
                          
                          return result;
                  
                      }
                  



                  In my methods I declare




                     @TransactionAttribute(TransactionAttributeType.REQUIRED)
                      @Interceptors( {InterceptorTransactionCM.class})
                      public void myMethod()
                      {
                  
                           ....
                  
                      }