6 Replies Latest reply on Nov 12, 2003 9:47 PM by alwyn

    CMR

    digitalmonkey

      I am trying to set up what should be a simple CMR with JBoss but although I can in fact get it working I feel sure the way it is set up cannot possibly be right.

      I have a two tables CUS and USR to which I want to set up a 1-many, many-1 bidirectional relationship


      The schemas of which are

      CUS (This is a table of Companies)
      ===
      CUS_UNIQUE (Key)
      ...

      USR (This is a table of individual users)
      ===
      USR_UNIQUE (key)
      USR_CUS_UNIQUE (contains a code corresponding to a key found in CUS_UNIQUE)


      The code as 'generated' is as shown below

      [ejb-jar.xml]
      ==============

      <ejb-relation-name>Company-User</ejb-relation-name>
      <ejb-relationship-role>
      company
      <ejb-relationship-role-name>company-has-users</ejb-relationship-role-name>
      One
      <relationship-role-source>
      company
      <ejb-name>Company</ejb-name>
      </relationship-role-source>
      <cmr-field>
      user
      <cmr-field-name>allUsers</cmr-field-name>
      <cmr-field-type>java.util.Collection</cmr-field-type>
      </cmr-field>
      </ejb-relationship-role>

      <ejb-relationship-role>
      user
      <ejb-relationship-role-name>user-belongs-to-company</ejb-relationship-role-name>
      Many
      <relationship-role-source>
      user
      <ejb-name>User</ejb-name>
      </relationship-role-source>
      <cmr-field>
      company
      <cmr-field-name>company</cmr-field-name>
      </cmr-field>
      </ejb-relationship-role>
      </ejb-relation>


      [jbosscmp-jdbc.xml]
      ===================
      <ejb-relation>
      <ejb-relation-name>Company-User</ejb-relation-name>
      <foreign-key-mapping />
      <ejb-relationship-role>
      <ejb-relationship-role-name>company-has-users</ejb-relationship-role-name>
      <key-fields>
      <key-field>
      <field-name>uniqueId</field-name>
      <column-name>CUS_UNIQUE</column-name> ****
      </key-field>
      </key-fields>
      </ejb-relationship-role>

      <ejb-relationship-role>
      <ejb-relationship-role-name>user-belongs-to-company</ejb-relationship-role-name>
      </ejb-relationship-role>
      </ejb-relation>


      However when run, JBoss complains because the field CUS_UNIQUE is not present in the USR_TBL table (and I am unable to simply change the names to suit)

      If I manually change the value at the line indicated by **** to the value USR_CUS_UNIQUE (note still keeping the name as uniqueId), then the application deploys and runs under JBoss 3.2.x.

      Surely this is not the right way of implementing this?

        • 1. Re: CMR
          viz

          Hi

          I've been struggling with this as well. After a bit of trial-and-error and testing I have got this to work.

          I have attached the files you might want to look at.

          Kind regards,
          --
          Marc

          • 2. Re: CMR
            hmr_mueller

            Hi,

            I have the same problems as reported above. I had a look at your files and they do not differ from mine, not obviously for me. The result is that JBoss creates the foreign key in the table of the 'many' side using the bean name of the 'one' side and the cmr-field of the 'one' side: <bean_name>_<cmr_field_name>. The specification of the key-field element in the jbosscmp-jdbc.xml has no effect. When creating the table manually with the desired column name for the foreign key column, the container throws an SQL-Exception that the foreign key column does not exist.
            I'm using Oracle database. Attached are the deployment descriptors. The JBoss 3.2.1 build:
            15:40:09,074 INFO [Server] JBoss (MX MicroKernel) [3.2.1 (build: CVSTag=JBoss_3_2_1 date=200305041533)] Started in 17s:835ms

            What's going wrong?

            • 3. Re: CMR
              cwolf2

              Hi,


              It certainly does appear that the column-name tag (in the key-fields section of the ejb-relationship-role for the ONE-SIDE of a one-many relationship) defines the foreign key's column name in the MANY-SIDE table and can be quite different from the primary key's column name, for example (from Viz's post above):


              <jbosscmp-jdbc>

              <enterprise-beans>


              <ejb-name>CustomerEJB</ejb-name>
              <table-name>CUSTOMER</table-name>

              <cmp-field>
              <field-name>id</field-name>
              <column-name>ID</column-name>
              <auto-increment/>
              </cmp-field>
              ...


              </enterprise-beans>


              <ejb-relation>
              <ejb-relation-name>Customer-Addresses</ejb-relation-name>
              <foreign-key-mapping/>
              <ejb-relationship-role>
              <ejb-relationship-role-name>Customer-has-many-Addresses</ejb-relationship-role-name>
              <key-fields>
              <key-field>
              <!-- The primary key in the CUSTOMER table -->
              <field-name>id</field-name>
              <!-- The foreign key column in the ADDRESS table -->
              <column-name>CUSTOMERFK_ID</column-name>
              </key-field>
              </key-fields>
              </ejb-relationship-role>
              ...


              </jbosscmp-jdbc>

              creates a one-many mapping between (database) columns CUSTOMER.ID and ADDRESS.CUSTOMERFK_ID.


              To me this is neither intuitive, nor obvious from the documentation.

              It is, however, obviously very useful to be able to specify a different column name for a foreign key to the primary key's column name, for example:

              * when working with a system that has already been defined that way (as per digitalmonkey's original post)

              * for a self-referential one-many relationship (e.g. in the "classic" employee/manager relationship the foreign key column name, say EMPLOYEE.MANAGER_ID, cannot be the same as the primary key's, say EMPLOYEE.ID)

              * where there are two one-many relationships between two EJB's (e.g. TradeEJB has two relationships with CurrencyEJB - one representing trade currency, say GBP, and one representing settlement currency, say USD)



              Chris.


              P.S. I've been using JBoss 3.2.1 for all the above.

              • 4. Re: CMR
                pietro.martinelli

                I've tryed to use your example of CMR with JBoss, and have the ejb-jar.xml and jbosscmp-jdbc.xml file with XDoclet1.2b4 generated. The files look identical to your files. But... JBoss deploy correctly well my application, but when I try to call the "getAllUsers" method I encounter the following error:

                A CMR collection may only be used within the transction in which it was created

                Can you help my ?
                Thank's, and.. I'm sorry for my very very orrible english !!!

                Pie.

                • 5. Re: CMR
                  aparaapara

                  It just means that you cannot return a CMR connection to your client unless your client is the one who started the connection. In general, you would wrap your entity beans with a session facade.

                  The facade would start a TX, get any CMR collections it needs. Modify them as necessary, and return some results to the client. At which point the TX ends.

                  -AP_

                  • 6. Re: CMR
                    alwyn

                    Ok.

                    Say for instance you do not want to add or remove elements from the Collection, but want to access individual data members on the local interfaces.

                    Would it be better then to have the session bean facade build value-objects (even if accessed locally) than creating the transaction within the client session bean and accessing the CMR Local interfaces directly in the client session bean?