2 Replies Latest reply on Nov 11, 2013 8:12 AM by dxmann73

    @Transactional not working correctly with @Stereotype wrt. Exception handling

    dxmann73

      Hi,

       

      suppose I have a @Stereotype with a @Transactional annotation:

       

      @Named

      @ViewScoped

      @Transactional

      @Stereotype

      @Retention (RetentionPolicy.RUNTIME)

      @Target (ElementType.TYPE)

      public @interface Boundary

      { }

       

      I annotate a CDI Bean with this stereotype

       

      @Boundary

      public class BusinessLogic {

         public void doSomething(){

              throw new RuntimeException("foo");

         }

      }

       

      If any exceptions are thrown when calling the business method, the user will get the (incorrect) info that the Class is missing a @Transactional annotation, because the Interceptor doesn't bother to look further into the Stereotype (see below).

       

      What's worse, the interceptor is swallowing the real exeption in the process. We get the following Stacktrace:

       

      java.lang.RuntimeException: ARJUNA016107: Expected an @Transactional annotation at class and/or method level

              at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.getTransactional(TransactionalInterceptorBase.java:61)

              at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.handleException(TransactionalInterceptorBase.java:96)

              at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:72)


      Which is pretty clear from the implementation of TransactionalInterceptorBase (taken from here):


          private Transactional getTransactional(InvocationContext ic) {

       

              Transactional transactional = ic.getMethod().getAnnotation(Transactional.class);

              if (transactional != null) {

                  return transactional;

              }

       

              Class<?> targetClass = ic.getTarget().getClass();

              transactional = targetClass.getAnnotation(Transactional.class); // needs to look further

              if (transactional != null) {

                  return transactional;

              }

       

              throw new RuntimeException(jtaLogger.i18NLogger.get_expected_transactional_annotation()); // swallows the exception that occured at ic.proceed()

          }


      Workaround ist to explicitly declare @Transactional at class level, so fixing this is not a top priority for us. Just wanted to let you guys know. :-)


      Kind regards,

      David Mann