5 Replies Latest reply on Jun 13, 2003 4:19 AM by arne

    requirement 18.3.7 from EJB 2.1

    arne

      The EJB spec tells in 18.3.7 (on javax.ejb.NoSuchEntityException):

      >>(...) To give the client a better indication of the cause of the error, the Container should throw the
      java.rmi.NoSuchObjectException (which is a subclass of java.rmi.RemoteException)
      to a remote client, or the javax.ejb.NoSuchObjectLocalException to a local client.<<

      This item seems not to be met by any version of JBoss. To address this item properly the class AbstractTyInterceptor (in JBoss 3.0.x / 3.2.x) or TxSupport (in current development) could be changed by appending something like the following code snippet between the rethrowing of the exception if it is an application exception and the following setRollbackOnly method call:

      if (t instanceof NoSuchEntityException)
      {
      NoSuchEntityException nsee = (NoSuchEntityException)t;
      if (type.isLocal())
      {
      throw new NoSuchObjectLocalException(
      nsee.getMessage(),
      nsee.getCausedByException());
      } else {
      NoSuchObjectException nsoe = new NoSuchObjectException(nsee.getMessage());

      // set the detail of the exception
      ((NoSuchObjectException)nsoe).detail =
      nsee.getCausedByException();

      throw nsoe;
      }
      }


      I would appreciate it very much if this change could be incorporated in a future version of JBoss 3.0.x or 3.2.x since our application would profit by large from NoSuchObjectExceptions not rolling back the current transaction.

      Yours sincerely
      Arne Siegel

        • 1. Re: requirement 18.3.7 from EJB 2.1

          JBoss 3.0/3.2 are EJB2.0, but that spec has
          the same clause in 18.3.4

          First you missed part of the clause, the bit
          you missed was:

          "The NoSuchEntityException is a subclass of EJBException. If it is thrown by a method of an
          entity bean class, the Container must handle the exception using the rules for EJBException
          described in Sections 18.3.1, 18.3.2, and 18.3.3."

          Which specifies a rollback.

          In fact NoSuchObjectException is a RemoteException
          and NoSuchObjectLocalException is an EJBException,
          both require a rollback according to the spec.

          Later in 18.4.2.1 you will find a clause stating
          that a transaction rolled back should be thrown
          to indicate to the client not to proceed when they
          started the tx.
          You will find the "no such object" is wrapped in
          a "transaction rolled back" by jboss when the
          caller starts the tx.

          Regards,
          Adrian

          • 2. Re: requirement 18.3.7 from EJB 2.1
            arne

            My intent in first place is the requirement 9.5.3 (from EJB 2.0): "After an entity object has been removed, subsequent attempts to access the entity object by a remote client
            result in the java.rmi.NoSuchObjectException."

            The current behaviour is a TransactionRolledBackException, which is absolutely unsatisfactory. I would like to make the decision myself whether to rollback or continue the transaction. I would like to be able to code

            MyEntity x;
            try {
            x = myEntityHome.findByPrimaryKey(pk);
            x.someMethod();
            } catch (ObjectNotFoundException) { // from findBy....
            throw new MyEntityNotFoundException();
            } catch (NoSuchObjectException) { // from someMethod...
            throw new MyEntityNotFoundException();
            // (treating this case as if the initial findBy... had not found the entity, as it would on the next transaction)
            }
            // do something with x ....

            In our application there exist entity beans that are concurrently accessed by one thread and removed by another thread. This inevitable leads to the situation that sometimes the entity bean achieved by a findBy... method cannot be accessed by the subsequent method call (at the time it obtains its entity instance lock the instance no longer exists).

            One way to achieve this goal was expressed by my initial proposition, because it seems to me the NoSuchEntityException was introduced with the intention in mind to enable such solutions.

            IMHO the paragraph cited by you is in conflict with other parts of the specification and also in conflict with the intention of its makers. Please observe that at no place is being expressed a need that a NoSuchObjectException had to be connected with a rollback of the current transaction.

            I see your point in interpreting these conflicting requirements in the most restrictive way so you don't risk being accused not to fulfil the spec. Perhaps the spec should be made more precise at this point.

            Best regards,
            Arne

            • 3. Re: requirement 18.3.7 from EJB 2.1
              arne

              My intent in first place is the requirement 9.5.3 (from EJB 2.0): "After an entity object has been removed, subsequent attempts to access the entity object by a remote client
              result in the java.rmi.NoSuchObjectException."

              The current behaviour is a TransactionRolledBackException, which is absolutely unsatisfactory. I would like to make the decision myself whether to rollback or continue the transaction. I would like to be able to code

              MyEntity x;
              try {
              x = myEntityHome.findByPrimaryKey(pk);
              x.someMethod();
              } catch (ObjectNotFoundException) { // from findBy....
              throw new MyEntityNotFoundException();
              } catch (NoSuchObjectException) { // from someMethod...
              throw new MyEntityNotFoundException();
              // (treating this case as if the initial findBy... had not found the entity, as it would on the next transaction)
              }
              // do something with x ....

              In our application there exist entity beans that are concurrently accessed by one thread and removed by another thread. This inevitable leads to the situation that sometimes the entity bean achieved by a findBy... method cannot be accessed by the subsequent method call (at the time it obtains its entity instance lock the instance no longer exists).

              One way to achieve this goal was expressed by my initial proposition, because it seems to me the NoSuchEntityException was introduced with the intention in mind to enable such solutions.

              IMHO the paragraph cited by you is in conflict with other parts of the specification and also in conflict with the intention of its makers. Please observe that at no place is being expressed a need that a NoSuchObjectException had to be connected with a rollback of the current transaction.

              I see your point in interpreting these conflicting requirements in the most restrictive way so you don't risk being accused not to fulfil the spec. Perhaps the spec should be made more precise at this point.

              Best regards,
              Arne

              • 4. Re: requirement 18.3.7 from EJB 2.1
                arne

                To teach our JBoss application the desired behavior (throwing NoSuchObjectException when the entity was removed) I am experimenting with a modified container configuration where the class org.jboss.ejb.plugins.TxInterceptorCMT is replaced by the attached class patch.org.jboss.ejb.plugins.RelaxedTxInterceptorCMT.

                I have tested it with 3.0.6 with good results, but it should work with 3.0.7 and 3.2.1 also.

                • 5. Re: requirement 18.3.7 from EJB 2.1
                  arne

                  In fact JBoss 3.2.1 requires some minor changes to my patched interceptor, because the invocation type is no longer represented by an int value, it has gotten its own InvocationType class.

                  Attached is the RelaxedTxInterceptorCMT version that I have sucessfully tested with JBoss 3.2.1.