7 Replies Latest reply on Nov 26, 2002 3:00 PM by sdmb

    JBoss 3.0.4 CMR Transaction troubles

    sdmb

      Code run in servlet:

      BankLocalHome bnkHome = BankUtil.getLocalHome();
      String bnkName = (String) req.getParameter("bank-name");
      BankLocal bank = bnkHome.findByPrimaryKey( bnkName );
      Set accounts = bank.getAccounts();
      Iterator iterator = accounts.iterator();

      The moment I call the "iterator" function on the set, I receive:

      java.lang.IllegalStateException: A CMR collection may only be used within the transction in which it was created
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.getIdList(RelationSet.java:58)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.iterator(RelationSet.java:260)

      There is no mention of "transaction" in either my ejb-jar.xml or web.xml descriptors, I had thought that this would mean there would be no transaction support. How do I explicitly turn off this behavior? Or is this simply a bug in JBoss 3.0.4 (Windows 2000, Sun JDK 1.4.1_01)?

      How can I get past this inability to simply iterate over a CMR collection?

        • 1. Attaching EAR file
          sdmb

          If this is any help finding a solution...

          • 2. Other JBoss build behavior
            sdmb

            JBoss 3.2.0beta -- same error
            JBoss 3.0.3 -- same error
            JBoss 3.0.0 -- works as expected

            • 3. Spoke too soon on JBoss 3.0.0
              sdmb

              JBoss 3.0.0 also shows this behavior. Obviously I am missing something when it comes to CMR and transactional integrity.

              How do I close a transaction, when I am not aware of having started one? This is very frustrating.

              • 4. Re: Spoke too soon on JBoss 3.0.0
                bleupen

                Hey,

                the getAccounts() CMR method probablyu started its own transaction b/c your Servlet did not.

                you need to convert the CMR Collection into a collection of entities. For example:

                public static Collection convert(Collection col, Class cls)
                {
                Collection results = new ArrayList();
                Object[] ouArray = (Object[])col.toArray((Object[])Array.newInstance(cls,new int[]{0}));
                results = Arrays.asList(ouArray);
                return results;
                }

                • 5. Re: Spoke too soon on JBoss 3.0.0
                  sdmb

                  Thanks for the response!

                  How can I simply keep getAccounts() CMR method from starting its own transaction? I will have to try your method of tricking out the data.

                  • 6. Re: Spoke too soon on JBoss 3.0.0
                    scoy

                    You need to do some research into fundamental J2EE patterns. Have a look at http://www2.theserverside.com/home/index.jsp for starters.

                    In essence, you need to write a session bean that provides services to your servlet.

                    One of these services would be to return a collection of account data (not necessarily the entities themselves) related to a particular bank.

                    The strength of this is it allows you to use container managed transactions (which is way easier than doing your own transaction management) and perform all the "heavy" work using local interfaces.

                    Steve Coy

                    • 7. Re: Spoke too soon on JBoss 3.0.0
                      sdmb

                      Thanks. I was doing the "session" providing access in other applications, but I guess I didn't realise the transaction-goodness it provided behind the scenes. This is exactly what I was looking for.