10 Replies Latest reply on Jul 7, 2004 11:16 AM by Matt Parker

    CMR collection may only be used within the transction in whi

    Matt Parker Newbie

      I'm having trouble getting CMR to work via XDoclet and was wondering if someone can point me in the right direction. I have a many-to-many relationship setup between two entities, Agents and SearchEngines. I would like to have a method in Agents that returns all the Search Engines the user has identified to query.

      I'm using JBoss 3.2.3 and MS Access 2000 just to test XDoclet and CMR.

      When I use the method, I get the following error:


      javax.servlet.ServletException: A CMR collection may only be used within the transction in which it was created
      at org.kart.agents.actions.LoadAction.execute(Unknown Source)
      at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:465)
      at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
      at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1422)
      at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:505)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:220)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2417)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:197)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:781)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:549)
      at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
      at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
      at java.lang.Thread.run(Thread.java:536)


      root cause

      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:66)
      at org.jboss.ejb.plugins.cmp.jdbc.bridge.RelationSet.toArray(RelationSet.java:327)
      at org.kart.agents.actions.LoadAction.execute(Unknown Source)
      at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:465)
      at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
      at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1422)
      at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:505)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:220)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2417)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:197)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:781)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:549)
      at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
      at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
      at java.lang.Thread.run(Thread.java:536)



        • 1. Re: CMR collection may only be used within the transction in
          Matt Parker Newbie

          Here are the relevant class:

          package org.kart.ejb.impl;
          
          import org.kart.util.GUID;
          import org.kart.ejb.AgentPK;
          import org.kart.common.ejb.User;
          import java.rmi.RemoteException;
          import java.util.Collection;
          
          import javax.ejb.CreateException;
          import javax.ejb.EntityBean;
          import javax.ejb.EntityContext;
          import javax.ejb.RemoveException;
          
          /**
           *
           * This is the bean representing an Agent.
           *
           * @ejb.bean
           * cmp-version="2.x"
           * local-jndi-name="KART/Agent"
           * name="Agent"
           * type="CMP"
           * view-type="local"
           *
           * @ejb.persistence
           * table-name="Agents"
           *
           * @ejb:finder
           * signature="java.util.Collection findByUser(java.lang.String userId)"
           * unchecked="true"
           * query="SELECT DISTINCT OBJECT (agent) FROM Agent agent WHERE agent.userId=?1"
           *
           * @ejb:finder
           * signature="com.parker.ejb.Agent findByName(java.lang.String userId, java.lang.String agentName)"
           * unchecked="true"
           * query="SELECT DISTINCT OBJECT (agent) FROM Agent agent WHERE agent.userId=?1 and agent.name=?2"
           *
           * @ejb.finder
           * signature="java.util.Collection findAll()"
           * unchecked="true"
           * query="SELECT DISTINCT OBJECT (agent) FROM Agent agent"
           *
           * @ejb.interface
           * local-extends="javax.ejb.EJBLocalObject"
           *
           * @ejb.transaction
           * type="Required"
           *
           * @ejb.ejb-ref
           * ejb-name="SearchEngine"
           * view-type="local"
           * ref-name="ejb/SearchEngineLocal"
           *
           * JBoss/JAWS CMP specific
           * @jboss:container-configuration name="Standard CMP 2.x EntityBean"
           * @jboss:table-name Agents
           * @jboss:create-table true
           * @jboss:remove-table false
           * @jboss:tuned-updates true
           * @jboss:read-only false
           *
           * @author map
           * @version 1.0
           *
           */
          public abstract class AgentBean implements EntityBean {
          
           EntityContext ctx = null;
          
           //EJB Callbacks
           public void ejbActivate() throws RemoteException {}
           public void ejbRemove() throws RemoteException, RemoveException {}
           public void ejbPassivate() throws RemoteException {}
           public void ejbLoad() throws RemoteException {}
           public void ejbStore() throws RemoteException {}
           public void setEntityContext( EntityContext ctx ) throws RemoteException { this.ctx = ctx; }
           public void unsetEntityContext() throws RemoteException { ctx = null; }
          
           /**
           * @ejb.create-method
           */
           public AgentPK ejbCreate( User user ) throws CreateException {
           setId( GUID.newString() );
           setUserId( user.getId() );
           return null;
           }
          
           public void ejbPostCreate( User user ){
          
           }
          
           /**
           * @ejb.persistence column-name="id"
           * @ejb.interface-method
           * @ejb.pk-field
           */
           public abstract String getId();
          
           public abstract void setId(String id);
          
           /**
           * @ejb.persistence column-name="name"
           * @ejb.interface-method
           */
           public abstract String getName();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setName( String name );
          
           /**
           * @ejb.persistence column-name="description"
           * @ejb.interface-method
           */
           public abstract String getDescription();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setDescription( String description );
          
           /**
           * @ejb.persistence column-name="query"
           * @ejb.interface-method
           */
           public abstract String getQuery();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setQuery( String query );
          
           /**
           * @ejb.persistence column-name="levels_deep"
           * @ejb.interface-method
           */
           public abstract int getLevelsDeep();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setLevelsDeep( int levelsDeep );
          
           /**
           * @ejb.persistence column-name="user_id"
           * @ejb.interface-method
           */
           public abstract String getUserId();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setUserId( String id );
          
          
           /**
           * @ejb.interface-method
           *
           * @ejb.relation
           * name="agent-search-engine"
           * role-name="agent-has-search-engine"
           * target-ejb="SearchEngine"
           *
           * @jboss.relation
           * related-pk-field="id"
           * fk-column="agent_id"
           *
           * @jboss.relation-mapping
           * style="relation-mapping"
           *
           * @jboss.relation-table
           * table-name="agent_search_engines"
           * create-table="false"
           */
           public abstract Collection getSearchEngines();
           /**
           * @ejb.interface-method
           */
           public abstract void setSearchEngines( Collection searchEngines );
          }
          
          



          package org.kart.ejb.impl;
          
          import org.kart.util.GUID;
          import org.kart.ejb.SearchEnginePK;
          
          import java.rmi.RemoteException;
          import java.util.Collection;
          
          import javax.ejb.CreateException;
          import javax.ejb.EntityBean;
          import javax.ejb.EntityContext;
          import javax.ejb.RemoveException;
          
          /**
           *
           * This is the bean representing an Search Engine.
           *
           * @ejb.bean
           * cmp-version="2.x"
           * local-jndi-name="KART/SearchEngine"
           * name="SearchEngine"
           * type="CMP"
           * view-type="local"
           *
           * @ejb.persistence
           * table-name="search_engines"
           *
           * @ejb.finder
           * signature="java.util.Collection findAll()"
           * unchecked="true"
           * query="SELECT DISTINCT OBJECT (searchengine) FROM SearchEngine searchengine"
           *
           * @ejb:finder
           * signature="com.parker.ejb.SearchEngine findByName(java.lang.String name)"
           * unchecked="true"
           * query="SELECT DISTINCT OBJECT (searchengine) FROM SearchEngine searchengine WHERE searchengine.name=?1"
           *
           * @ejb.interface
           * local-extends="javax.ejb.EJBLocalObject"
           *
           * @ejb.transaction
           * type="Required"
           *
           * @ejb.ejb-ref
           * ejb-name="Agent"
           * view-type="local"
           * ref-name="ejb/AgentLocal"
           *
           * JBoss/JAWS CMP specific
           * @jboss.container-configuration name="Standard CMP 2.x EntityBean"
           * @jboss.table-name search_engines
           * @jboss.create-table true
           * @jboss.remove-table false
           * @jboss.tuned-updates true
           * @jboss.read-only false
           *
           * @author map
           * @version 1.0
           *
           */
          public abstract class SearchEngineBean implements EntityBean {
          
           EntityContext ctx = null;
          
           //EJB Callbacks
           public void ejbActivate() throws RemoteException {}
           public void ejbRemove() throws RemoteException, RemoveException {}
           public void ejbPassivate() throws RemoteException {}
           public void ejbLoad() throws RemoteException {}
           public void ejbStore() throws RemoteException {}
           public void setEntityContext( EntityContext ctx ) throws RemoteException { this.ctx = ctx; }
           public void unsetEntityContext() throws RemoteException { ctx = null; }
          
           /**
           * @ejb.create-method
           */
           public SearchEnginePK ejbCreate() throws CreateException {
           setId( GUID.newString() );
           return null;
           }
          
           public void ejbPostCreate(){
          
           }
          
           /**
           * @ejb.persistence column-name="id"
           * @ejb.interface-method
           * @ejb.pk-field
           */
           public abstract String getId();
          
           public abstract void setId(String id);
          
           /**
           * @ejb.persistence column-name="name"
           * @ejb.interface-method
           */
           public abstract String getName();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setName( String name );
          
           /**
           * @ejb.persistence column-name="description"
           * @ejb.interface-method
           */
           public abstract String getDescription();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setDescription( String description );
          
           /**
           * @ejb.persistence column-name="hidden_parameters"
           * @ejb.interface-method
           */
           public abstract String getHiddenParameters();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setHiddenParameters( String hiddenParameters );
          
           /**
           * @ejb.persistence column-name="query_variable"
           * @ejb.interface-method
           */
           public abstract String getQueryVariable();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setQueryVariable( String queryVariable );
          
           /**
           * @ejb.persistence column-name="url"
           * @ejb.interface-method
           */
           public abstract String getUrl();
          
           /**
           * @ejb.interface-method
           */
           public abstract void setUrl( String url );
          
          
           /**
           * @ejb.interface-method
           *
           * @ejb.relation
           * name="agent-search-engine"
           * role-name="search-engine-has-agent"
           * target-ejb="Agent"
           *
           * @jboss.relation
           * related-pk-field="id"
           * fk-column="search_engine_id"
           *
           * @jboss.relation-table
           * table-name="agent_search_engines"
           * create-table="false"
           *
           * @jboss.relation-mapping
           * style="relation-mapping"
           */
           public abstract Collection getAgents();
           public abstract void setAgents( Collection agents );
          }
          

          =============================================
          =============================================

          And the generated xml descriptor (jbosscmp-jdbc) concerning the relationships.

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 3.2//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_3_2.dtd">
          
          <jbosscmp-jdbc>
           <defaults>
           <datasource>java:/KartDS</datasource>
           <datasource-mapping>MS SQLSERVER2000</datasource-mapping>
           <preferred-relation-mapping>foreign-key</preferred-relation-mapping>
           </defaults>
          
           <enterprise-beans>
          
           <!--
           To add beans that you have deployment descriptor info for, add
           a file to your XDoclet merge directory called jbosscmp-jdbc-beans.xml
           that contains the <entity></entity> markup for those beans.
           -->
          
           <entity>
           <ejb-name>User</ejb-name>
           <create-table>true</create-table>
           <remove-table>false</remove-table>
           <read-only>false</read-only>
           <table-name>Users</table-name>
          
           <cmp-field>
           <field-name>id</field-name>
           <column-name>id</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>isAdmin</field-name>
           <column-name>admin</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>password</field-name>
           <column-name>password</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>username</field-name>
           <column-name>user_name</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>firstName</field-name>
           <column-name>first_name</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>lastName</field-name>
           <column-name>last_name</column-name>
          
           </cmp-field>
          
          <!-- jboss 3.2 features -->
          <!-- optimistic locking does not express the exclusions needed -->
           </entity>
          
           <entity>
           <ejb-name>Agent</ejb-name>
           <create-table>true</create-table>
           <remove-table>false</remove-table>
           <read-only>false</read-only>
           <table-name>Agents</table-name>
          
           <cmp-field>
           <field-name>id</field-name>
           <column-name>id</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>name</field-name>
           <column-name>name</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>description</field-name>
           <column-name>description</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>query</field-name>
           <column-name>query</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>levelsDeep</field-name>
           <column-name>levels_deep</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>userId</field-name>
           <column-name>user_id</column-name>
          
           </cmp-field>
          
          <!-- jboss 3.2 features -->
          <!-- optimistic locking does not express the exclusions needed -->
           </entity>
          
           <entity>
           <ejb-name>SearchEngine</ejb-name>
           <create-table>true</create-table>
           <remove-table>false</remove-table>
           <read-only>false</read-only>
           <table-name>search_engines</table-name>
          
           <cmp-field>
           <field-name>id</field-name>
           <column-name>id</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>name</field-name>
           <column-name>name</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>description</field-name>
           <column-name>description</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>hiddenParameters</field-name>
           <column-name>hidden_parameters</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>queryVariable</field-name>
           <column-name>query_variable</column-name>
          
           </cmp-field>
           <cmp-field>
           <field-name>url</field-name>
           <column-name>url</column-name>
          
           </cmp-field>
          
          <!-- jboss 3.2 features -->
          <!-- optimistic locking does not express the exclusions needed -->
           </entity>
          
           </enterprise-beans>
          
           <relationships>
           <ejb-relation>
           <ejb-relation-name>agent-search-engine</ejb-relation-name>
           <relation-table-mapping>
           <table-name>agent_search_engines</table-name>
           <create-table>false</create-table>
           </relation-table-mapping>
          
           <ejb-relationship-role>
           <ejb-relationship-role-name>agent-has-search-engine</ejb-relationship-role-name>
           <key-fields>
           <key-field>
           <field-name>id</field-name>
           <column-name>search_engine_id</column-name>
           </key-field>
           </key-fields>
          
           </ejb-relationship-role>
           <ejb-relationship-role>
           <ejb-relationship-role-name>search-engine-has-agent</ejb-relationship-role-name>
           <key-fields>
           <key-field>
           <field-name>id</field-name>
           <column-name>agent_id</column-name>
           </key-field>
           </key-fields>
          
           </ejb-relationship-role>
           </ejb-relation>
           </relationships>
          
          </jbosscmp-jdbc>
          


          • 2. Re: CMR collection may only be used within the transction in
            Kabir Khan Master

            Is your code executing within a transaction, for example called from a session bean with tx-attribute=Required?

            If not, a new Tx will be created for every call to the entity bean, which would/should give the results you get.

            • 3. Re: CMR collection may only be used within the transction in
              Kabir Khan Master

              i.e. the finder executes in one Tx, and the CMR access in another Tx

              • 4. Re: CMR collection may only be used within the transction in
                Matt Parker Newbie

                I set the XDoclet tag

                * @ejb.transaction
                * type="Required"

                at the class level, which I thought imposed transactions on every method unless specifically overridden. Would this cover what you are talking about?

                The implementation in question is a struts class that gets a reference to AgentHome, returns the AgentEJB in question, and also returns all associated SearchEngine EJBs via the agent's getSearchEngines() method.

                • 5. Re: CMR collection may only be used within the transction in
                  Matt Parker Newbie

                  The code is essentially the following:

                   ctx = new InitialContext();
                   HttpSession session = request.getSession();
                   home = (AgentHome)ctx.lookup( AgentHome.JNDI_NAME );
                  
                   //Use this method to retrieve a parameter from the request.
                   String id = request.getParameter("id");
                   agent = home.findByPrimaryKey( new AgentPK(id) );
                   log.debug("Agent "+id+" retrieved");
                  
                   EditAgentForm eaf = new EditAgentForm();
                   eaf.setId( agent.getId() );
                   eaf.setName( agent.getName() );
                   eaf.setDescription( agent.getDescription() );
                   eaf.setQuery( agent.getQuery() );
                   eaf.setUserId( agent.getUserId() );
                  
                   Collection engines = agent.getSearchEngines();
                  


                  • 6. Re: CMR collection may only be used within the transction in
                    Matt Parker Newbie

                    The getCollection() method returns fine. But when I try to get an iterator, to return an array from the colleciton using toArray(), it gives me the error message posted above.

                    • 7. Re: CMR collection may only be used within the transction in
                      Matt Parker Newbie

                      Sorry. I meant getSearchEngines(), not getColletion().

                      • 8. Re: CMR collection may only be used within the transction in
                        Kabir Khan Master

                        From what you post, it does not look like the caller is in a transaction.

                        This causes:
                        agent = home.findByPrimaryKey( new AgentPK(id) ); //to start and complete a new transaction for the call

                        eaf.setId( agent.getId() );//to start and complete a new transaction for the call
                        :
                        Collection engines = agent.getSearchEngines();//to start and complete a new transaction for the call



                        If the caller is in a a Tx, all the entity bean methods will be executed as part of the existing Tx. The most common way to acheive this is to have your struts Action call a SSB (Session Facade) that has trans-attribute=Required, and to use a data transfer object to pass the values from the facade back to the caller.

                        An alternative would be to manage the transactions yourself by using User transactions, along the lines of:

                        UserTransaction tx = null;
                        try
                        {
                        InitialContext ctx = new InitialContext();
                        tx = (UserTransaction) ctx.lookup("UserTransaction");
                        tx.begin();


                        //Do your stuff

                        if (tx.getStatus() == Status.STATUS_ACTIVE)
                        {
                        tx.commit();
                        }
                        return table;
                        }
                        catch (Exception e)
                        {
                        if (tx != null) tx.rollback();
                        }




                        • 9. Re: CMR collection may only be used within the transction in
                          Kabir Khan Master

                          Oooops

                          UserTransaction tx = null;
                          try
                          {
                           InitialContext ctx = new InitialContext();
                           tx = (UserTransaction) ctx.lookup("UserTransaction");
                           tx.begin();
                          
                          
                           //Do your stuff
                          
                           if (tx.getStatus() == Status.STATUS_ACTIVE)
                           {
                           tx.commit();
                           }
                          
                          }
                          catch (Exception e)
                          {
                           if (tx != null) tx.rollback();
                          }


                          • 10. Re: CMR collection may only be used within the transction in
                            Matt Parker Newbie

                            Thanks! I greatly appreciate your prompt replies.