2 Replies Latest reply on Nov 21, 2008 2:11 PM by Olivier Thierry

    reference is invalid error after exception

    Olivier Thierry Apprentice


      I wrote unit tests for Seam components, using Seam 2.1.0.SP1 and HSQLDB as database. One of these tests saves an entity in database, then tries to save a duplicate one (unique constraint on code property of my entity) and then deletes the entity. Here is the unit test I wrote.

      public void testSaveAndDeleteOrganization()  throws java.lang.Exception
          new ComponentTest() {
              public void testComponents() throws java.lang.Exception {
                  OrganizationInternalServiceLocal service = (OrganizationInternalServiceLocal) getInstance("organizationInternalService"); 
                  // Create an organization
                  Organization organization = new Organization();
                  organization.setDescription("ORG_TEST description");
                  organization.setName("ORG_TEST name");
                  organization = service.saveOrganization(organization);
                  assert organization.getId() != null;
                  // Create a duplicate organization
                  // We should get an exception
                  Organization duplicateOrganization = new Organization();
                  duplicateOrganization.setDescription("ORG_TEST description");
                  duplicateOrganization.setName("ORG_TEST name");
                  try {
                      duplicateOrganization = service.saveOrganization(duplicateOrganization);
                      assert false;
                  catch (Exception exception) {
                      assert true;
                  // Delete an organization
                  assert service.loadOrganization("ORG_TEST") == null;

      But when running this test, I get the following exception on deleteOrganization method call. (Note I overrode Seam test classes to use OpenEJB instead of JBoss embedded because of bugs with inheritance that made my tests crash, that's why you can see OpenEJB logs in the stack trace).

      testSaveAndDeleteOrganization(t4.core.commons.organization.internal.test.OrganizationInternalServiceTest)  Time elapsed: 0.062 sec  <<< FAILURE!
      javax.ejb.NoSuchEJBException: reference is invalid
              at org.apache.openejb.core.ivm.BaseEjbProxyHandler.isValidReference(BaseEjbProxyHandler.java:319)
              at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:232)
              at $Proxy120.deleteOrganization(Unknown Source)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:585)
              at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
              at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
              at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:76)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
              at org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.java:43)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
              at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54)
              at org.javassist.tmp.java.lang.Object_$$_javassist_11.deleteOrganization(Object_$$_javassist_11.java)
              at t4.core.commons.organization.internal.test.OrganizationInternalServiceTest$4.testComponents(OrganizationInternalServiceTest.java:204)
              at org.jboss.seam.mock.AbstractSeamTest$ComponentTest.run(AbstractSeamTest.java:163)
              at t4.core.commons.organization.internal.test.OrganizationInternalServiceTest.testSaveAndDeleteOrganization(OrganizationInternalServiceTest.java:144)

      If I remove the lines for duplicate organization test, I don't have the problem ! So it looks like my Seam component is down after an exception is thrown. I have the same problem for any test with a unique constraint violation.

      The organizationInternalService Seam component is CONVERSATION scoped and calls an organizationDao component (CONVERSATION scoped too). I use extended persistence context. All my components used to be STATELESS with no extended persistence context and the test used to work at that time. But I had to use extended persistence context because of lazy collections loading problems. Maybe persistence context is corrupted after an exception is thrown ? Is there something known about that ?

      Any help welcome ;)

        • 1. Re: reference is invalid error after exception
          Olivier Thierry Apprentice

          I made more tests to understand what the problem is exactly. I changed my component so that it uses neither persistence context, neither other components injection.

          saveOrganization method in organizationInternalService now just does this :

          if (organization.getCode().equals("ORG_TEST")) {
              organization.setId((long) 100000);
              return organization;
          else {
              throw new OrganizationDaoException();

          If I define the component with STATELESS scope, my test works OK. If I define it with CONVERSATION scope, it fails reference is invalid error ! So I am now convinced there's a problem when a method of a stateful component throws an exception ! Anyone encountered such a problem ? Does it look like a problem with Seam ? Or maybe a bug with Open EJB ?

          Please tell me if you have any idea about this ;)

          • 2. Re: reference is invalid error after exception
            Olivier Thierry Apprentice

            I was given an answer on OpenEJB user list :

            Whenever a system exception is thrown by any of the session
            bean's business methods the bean instance is discarded. In the case of
            stateless session beans each method call goes to an instance in the
            pool. It need not be the same instance. So even if the instance is
            discarded this is transparent to the bean developer.
            In the case of a stateful session bean, all the calls go to the same
            bean and so if the previous call threw a system exception then the
            corressponding stateful session instance will be discarded and you
            will get the javax.ejb.NoSuchEJBException.

            Use the @javax.ejb.ApplicationException annotation to specify that an
            exception class is an application exception.

            It works perfect in effect after adding this annotation.
            Hope it will help.