5 Replies Latest reply on Oct 24, 2002 6:32 AM by iris

    A CMR collection may only be used within the transction in w

    mozheyko_d

      <ejb-jar>
      ..................

      <ejb-relation>
      <ejb-relation-name>User-Pay</ejb-relation-name>
      <ejb-relationship-role>


      <ejb-relationship-role-name>user-has-pays</ejb-relationship-role-name>
      One
      <relationship-role-source>
      <ejb-name>UserBean</ejb-name>
      </relationship-role-source>
      <cmr-field>
      <cmr-field-name>userPays</cmr-field-name>
      <cmr-field-type>java.util.Set</cmr-field-type>
      </cmr-field>
      </ejb-relationship-role>
      <ejb-relationship-role>
      <ejb-relationship-role-name>pay-belongs-to-user</ejb-relationship-role-name>
      Many
      <cascade-delete/>
      <relationship-role-source>
      <ejb-name>PayBean</ejb-name>
      </relationship-role-source>
      <cmr-field>
      <cmr-field-name>user</cmr-field-name>
      </cmr-field>
      </ejb-relationship-role>
      </ejb-relation>

      .............
      </ejb-jar>


      <jbosscmp-jdbc>
      ..............

      <ejb-relation>
      <ejb-relation-name>User-Pay</ejb-relation-name>
      <foreign-key-mapping/>
      <ejb-relationship-role>
      <ejb-relationship-role-name>user-has-pays</ejb-relationship-role-name>
      <key-fields>
      <key-field>
      <field-name>name</field-name>
      <column-name>user</column-name>
      </key-field>
      </key-fields>
      </ejb-relationship-role>

      <ejb-relationship-role>
      <ejb-relationship-role-name>pay-belongs-to-user</ejb-relationship-role-name>
      <key-fields/>
      </ejb-relationship-role>

      </ejb-relation>


      </jbosscmp-jdbc>


      User bean = userHome.findByPrimaryKey( "Froggy");
      Collection col = bean.getUserPays();

      WHY I SEE ERROR :
      A CMR collection may only be used within the transction in which it was cre ???????????????????????????????????

        • 1. Re: A CMR collection may only be used within the transction
          aloubyansky

          As it says: the collection is obtained in one transaction and then used in another. This is disallowed.
          If you don't see the reason, post the code where the collection is obtained and used.

          • 2. Re: A CMR collection may only be used within the transction
            minamoto

            >This is disallowed.
            by EJB 2.0 spec.
            See section 10.3.8 & 10.4.2.2.

            Miki

            • 3. Re: A CMR collection may only be used within the transction
              mozheyko_d

              How i can use CMR-METHOD getUserPays from my example ?

              • 4. Re: A CMR collection may only be used within the transction
                aloubyansky

                Wrap all the logic in one transaction.

                • 5. Re: A CMR collection may only be used within the transction
                  iris

                  Miki said: looking in the EJB 2.0 spec chapters 10.3.8 and 10.4.2.2.

                  I read those and they say:

                  "It is the responsability of the Container to throw the java.lang.IllegalStateException if an attempt is made to use a java.util.Iterator for a container-managed collection in a transaction context other than in which the iterator was obtained."

                  But in my code I use the iterator in the same method that
                  I obtained it and the exception is thrown.

                  Here is my code:

                  My User EJB:

                  /**
                  * This interface defines the local interface for the User Bean
                  */
                  public interface User extends EJBLocalObject {
                  public Integer getId() ;
                  public String getName() ;
                  public String getPassword() ;
                  public Collection getProfiles() ; <-- CMR collection
                  }

                  public abstract class UserBean implements EntityBean, Principal {
                  private EntityContext context ;

                  // Access methods for persistent fields

                  public abstract Integer getId() ;
                  public abstract void setId(Integer id) ;

                  public abstract String getName() ;
                  public abstract void setName(String name) ;

                  public abstract String getPassword() ;
                  public abstract void setPassword(String password) ;

                  // Access methods for relationship fields

                  public abstract Collection getProfiles() ;
                  public abstract void setProfiles(Collection profiles) ;

                  ....
                  }

                  My Profile EJB:

                  /**
                  * This interface defines the remote interface for the Profile Bean
                  */
                  public interface Profile extends EJBLocalObject {
                  // Access methods for persistent fields
                  public String getTitle() ;
                  }

                  /**
                  * This class contains the implementation for the methods specified in the home
                  * and local interfaces for the "Profile" EJB
                  */
                  public abstract class ProfileBean implements EntityBean {
                  private EntityContext context ;

                  // Access methods for persistent fields

                  public abstract Integer getId() ;
                  public abstract void setId(Integer id) ;

                  public abstract String getTitle() ;
                  public abstract void setTitle(String title) ;

                  ...
                  }

                  The code in which I use the CMR collection:

                  try {
                  Collection tmp = userHome.findByName(userName) ;
                  if ( tmp == null || tmp.isEmpty() ) return null ;
                  User user = (User)tmp.iterator().next() ;
                  System.out.println("User: "+user.getName()) ;
                  Collection profiles = user.getProfiles() ;
                  ArrayList principals = new ArrayList() ;
                  Iterator it = profiles.iterator(); // <-- here
                  for (; it.hasNext();) {
                  Profile profile = (Profile)it.next() ;
                  System.out.println("profil: "+profile.getTitle()) ;
                  principals.add(new MyPrincipal(profile.getTitle())) ;
                  }
                  return Collections.enumeration(principals) ;
                  } catch (FinderException find) {
                  System.err.println("FinderException") ;
                  return null ;
                  }

                  The exception is thrown on the line Iterator it = profiles.iterator(); // <-- here
                  so when I attempt to get the iterator, this not act as
                  described in the specification.

                  Is this a bug ?

                  Iris