3 Replies Latest reply on May 2, 2002 11:26 PM by shortpasta

    Transaction not rolled-back on CreateException

    shortpasta

      void createClient () throws Exception {
      Client c = clientHome.create (100, "Client 1"); // PK is 100
      ClientChild cc = clientHome.create (200, 50, "Client Child"); // PK is 200. FK to Client should have been 100
      }

      Line2 throws a javax.ejb.CreateException wrapping a java.sql.SQLException with message "Cannot add a child row: a foreign key constraint fails" which is great! Just as expected since the 50 should have been 100 instead.

      However, the Client record HAS been created, indicating that the transaction was NOT rolled-back. It looks like the transaction gets committed no matter what.

      Shouldn't have this transaction been rolled-back? What should I do to make it roll-back? [2.4.4 w mysql/innodb]

        • 1. Re: Transaction not rolled-back on CreateException
          chgrimm

          i suppose you did the two create exceptions in a session bean

          a create exception does not automatically lead to a transaction rollback

          if you want to achieve this, catch the create exception in the session bean and call ctx.setRollbackOnly() ( where ctx is your SessionContext instance )

          • 2. Re: Transaction not rolled-back on CreateException
            shortpasta

            Really? But even throwing an EJBException still commits the create on the first line, and it shouldn't!
            void createClient () throws Exception {
            Client c = clientHome.create (100, "Client 1"); // PK is 100
            ClientChild cc = clientHome.create (200, 50, "Client Child"); // PK is 200. FK to Client should have been 100
            throw new javax.ejb.EJBException ("Test transaction");
            }

            PS. Sorry for not answering sooner but I did not get a notification even though I was *watching* this topic....

            • 3. Re: Transaction not rolled-back on CreateException
              shortpasta

              The problem is in the first line -- my function prototype:
              "void createClient () throws Exception {"

              When you declare that you throw Exception, the rules don't apply. Well, you know what I mean.

              My best guess is that my ejb's method's declared exceptions are mapped directly to the stub. Because Exception is explicitly declared in my method, it ends up directly mapped, and ends up not even running the container's exception mapping routines which check for EJBException's /RuntimeException's in order to perform a rollback.

              I expected some kind of instanceof check on the exception being thrown, but instead it looks like the translation maps one-to-one with the throws clause in the ejb signature. So it looks like here are the mappings that should be followed:

              Create/Finder (where applicable)/Naming/EJB Exceptions should be wrapped inside an EJBException.
              Runtime/Remote Exceptions may be just be thrown or wrapped as you please.
              Business exceptions should be (according to the business) categorized as logical/system.

              The first 2 cases result in a container rollback & the last one in a commit.

              In all cases, to be ready for container swapping and remote calls, all exceptions should be wrapped into relative EJB/Remote/Business exceptions inherited form the omonymous library classes in order to circumvent java.lang.Exception's transient stack trace (at least if you want it).

              When I'll have all this figured out, I'll upload the wrapper classes myself. Maybe others will benefit from them.

              Cheers & thanks to all that replied.
              Ciao.