1 Reply Latest reply on Feb 9, 2003 5:48 PM by kirksc1

    CMR exception with collection

    kirksc1

      I am relatively new to CMP/CMR and have been creating a small application in order to reinforce what I have read. However, I am now receiving an exception that I don't believe I should be getting. The message suggests that multiple transactions are being created. However, ALL of my methods (in all EJBs) have a transaction setting of "Required". It is my understanding that "Required" will only create a new transaction if one has not been previously created. Therefore, I would think that any single EJB call would result in one and only one transaction. Can anyone give me an idea of where my thinking is wrong, or how I might accomplish the same goal?

      Exception Message:
      java.lang.IllegalStateException: A CMR collection may only be used within the transaction in which it was created

      Environment:
      jboss 3.0.4 with tomcat-4.1.x
      mysql 3.23.43

      Application Description:
      At this point the application simply tracks a User and its email addresses (along with a type - Home, Work, etc.). I have created a User Entity EJB and EmailAddress Entity EJB (both with local interfaces), as well as a UserManager Stateless Session Bean to handle all interaction with the entity beans. Updates to User data are provided to the UserManager in the form of UserValue objects (Value Object). Each UserValue also maintains a collection of EmailAddressValue objects (Value Object).

      The exception occurs when I try to update the User's data and an email address has been removed. Simply updating data works fine, and removing an email address removes the foreign key value. However, if a User removes an email address from their list I would like to completely remove the record from the database. Some source code snippets follow.

      Code from the UserManager SLSB:
      -------------------------------
      public UserValue updateUser(UserValue user) ... {

      //Look up the user and retrieve a Local reference
      UserLocal userLocal = userLocalHome.findByPrimaryKey(...);

      //Make User updates to the Local reference

      //Update email addresses
      updateEmailAddresses(userLocal, user.getEmailAddresses());

      //Build and return a fresh UserValue
      }

      private void updateEmailAddresses(UserLocal userLocal, Collection emailAddresses) ... {
      //Create a new Collection to contain EmailAddressLocal objects
      Collection emailAddressLocals = new ArrayList();

      //Iterate through emailAddresses
      //Look for the entry in the current email address entries
      //Update entries that are found
      //Create new entries if they are not found
      //Add entry to emailAddressLocals
      //End iteration

      //delete any email address entries that have been removed by the user
      deleteEmailAddresses(userLocal.getEmailAddresses(), emailAddressLocals);

      //Set email addresses
      userLocal.setEmailAddresses(emailAddressLocals);
      }

      private void deleteEmailAddresses(Collection origEmailAddresses, Collection newEmailAddresses) ... {
      //Iterate through origEmailAddresses
      //NOTE: THE EXCEPTION OCCURS WHEN I ASK FOR AN ITERATOR FROM THE origEmailAddresses COLLECTION
      //remove entry via EmailAddressLocalHome if newEmailAddresses does not contain the entry
      //End iteration
      }

      Sorry for the long post, but it helped me get everything straight in my own mind.

      Thanks for the help,

      Kirk

        • 1. Re: CMR exception with collection
          kirksc1

          I believe that I see one of my mistakes. I would expect to run into problems attempting to acquire 2 local references to the same bean. This would, of course, prevent me from comparing them.

          To fix this I switched the comparison to be a primary key match between the EmailAddressValues and the Local references. However, I am still getting the Exception I described above when I ask for an Iterator on the local reference's getEmailAddresses() method:

          local.getEmailAddresses().iterator();

          I then decided to just perform a simple straight read of the user's email addresses, which resulted in the same exception.

          Am I mistaken in thinking that a Collection returned from a CMR will contain local references of the related EJB (in this case EmailAddressLocal objects)? How else can I retrieve the email address data for the user?

          Any input would be greatly appreciated.

          Kirk