so what are your transaction settings? have you configured anything in your ejb-jar.xml?
I'am really confused at the moment. I haven't set up everything on the server.
I've tried an example I've found on sourceforge (The Gangsters ;) and this example is running without any error or warning. The difference is that I'm using xdoclet for generating all the descriptors and interfaces but the generated files seemed to be correct. The Transactions for the EntityBeans were set to Required for all methods.
The client is a simple JUnitEE TestSuite. The setUp() method creates the Entities and tearDown() removes them. The Creation seems to bee okay. one Testcase calls the setEjbA(ejbA) method of the EjbB. The next step is to get the Collection of all EjbB form the instance of EjbA. Everything is okay till then. And now comes the big bang. I try to call a method of the collection (No matter what kind of method).
If I use the collection inside the instance of EjbA all is running fine.
I have been used jboss for a long time and have never this problem until now. I deployed a lot of projects on it. This is my new project, and I have just copied the deploy configuration files of existing projects and modify them. And I got the same problem now, and really do not know what I did wrong.
Hope that some one can help us quickly.
The solution to the problem is hinted at by the error message: "A CMR collection may only be used within the transction in which it was created". Although I will admit that it took me a while to realize how to implement the fix when I first encountered this as well.
You need to embed the relevant client code within its own transaction. This means that you need to surround the CMR-related code with something like:
Context jndiContext = new InitialContext();
UserTransaction ut = (UserTransaction)
// CMR-handling code like:
Collection products = category.getProducts();
// end the transaction
I think that this transaction code is described in the JBoss Getting Started guide.
The fact that you had declared all of your EJB methods to have a Transaction setting of Required probably mislead you. JBoss created a separate Transaction for each method invocation. But CMR need one transaction across the fetching of the relation and manipulation of the relation (did I say that right?)
Maybe the CMR-based methods should have a Transaction setting of Mandatory?
This seems like a FAQ to me. Plus, I have never seen a book or document describe this particular CMR coding problem. Maybe the JBoss site can add a Hints or FAQ section for J2EE practical usage?
I would like to see sections on using Oracle and using CMR.
I will try your solution. But I wonder why my other project works without coding the transaction myself.
And another difference is that this code is not in the client, but is written in a method of a session bean. The client invoke this method. So I think that all steps of this method in the session will be invoked in a transaction on the server.
I notice that in the verifyIteratorIsValid() function of the RelationSet the setHandle is checked and if the set is null then the error
The iterator of a CMR collection may only be used within the transction in which it was created"
why doesn't verifyIteratorIsValid() check if the iterator is read only and let another transaction access it in that case. Isn't that the point of declaring
the getter read-only