CMR exception with collection
kirksc1 Feb 9, 2003 3:52 PMI 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