7 Replies Latest reply on Oct 22, 2003 3:29 PM by ronr

    Problem: One2Many CMR in JBoss 3.0.6/3.2.1

    danield

      I'm new to EJB and Jboss and have a problem with both.
      Configuration:
      - win2K
      - Sun JDK 1.4.1_02
      - JBoss 3.0.6/3.2.1
      - MySQL 4.0.12
      - mysql-connector 3.0.6/3.0.8

      I have two EntityBeans using CMP. An ejbA has a Relation with many ejbB.
      +-----------------------+ +------+
      | ejbA | | ejbB |
      +----------------- -----+<-------------->+------+
      |+Collection getEjbBs() | 1 n |... |
      |... | +------+
      +-----------------------+


      They are deployed without any error or warning.

      If I try to call the method Collection getEjbBs() all seems to be okay. But when I try to access the Collection I've got a java.lang.IllegalStateException: A CMR collection may only be used within the transaction it was created. But if I do the same inside the ejbA nothing goes wrong.

        • 1. Re: Problem: One2Many CMR in JBoss 3.0.6/3.2.1

          so what are your transaction settings? have you configured anything in your ejb-jar.xml?

          • 2. Re: Problem: One2Many CMR in JBoss 3.0.6/3.2.1
            tdang

            I got the same error, plz see under this post:

            http://www.jboss.org/modules/bb/index.html?module=bb&op=viewtopic&t=

            • 3. Re: Problem: One2Many CMR in JBoss 3.0.6/3.2.1
              danield

              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.

              • 4. Re: Problem: One2Many CMR in JBoss 3.0.6/3.2.1
                tdang

                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.

                • 5. Re: Problem: One2Many CMR in JBoss 3.0.6/3.2.1
                  tpaulson

                  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)
                  jndiContext.lookup("UserTransaction");
                  ut.begin();

                  // CMR-handling code like:
                  Collection products = category.getProducts();
                  products.add(new_product);

                  // end the transaction
                  ut.commit();


                  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.

                  • 6. Re: Problem: One2Many CMR in JBoss 3.0.6/3.2.1
                    tdang

                    Hi tpaulson,

                    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.


                    • 7. Re: Problem: One2Many CMR in JBoss 3.0.6/3.2.1
                      ronr

                      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"

                      is thrown

                      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