10 Replies Latest reply on May 30, 2004 9:04 AM by ironbird

    adding record to CMR field

    didi

      Hi everybody,

      I have to EJB with 1-N CMR field (properly configured with xdoclet).

      /**
      * @ejb:persistent-field
      *
      * @ejb:relation name="idLectureQuestion"
      * role-name="each-lecture-has-a-lot-of-questions"
      * target-ejb="QuestionEntity"
      * target-role-name="a-lot-of-questions-belong-to-one-lecture"
      * target-multiple="no"
      *
      * @jboss:target-relation related-pk-field="id"
      * fk-column="questions"
      *
      * @jboss:column-name name="questions"
      */
      public abstract Collection getQuestions();

      public abstract void setQuestions(Collection questions);



      now I tried to add a new Question to this field. So I created a new method in this EJB file which looks like that

      /**
      * @ejb:interface-method view-type="remote"
      */
      public void addQuestion(QuestionEntity question) {
      this.getQuestions().add(question);
      }

      But it is not working. I have the feeling that the new record is added to the Collection but it is somehow not written back to the bean.
      I remeber that I read something about just working with LocalInterfaces but I can not find the text again.

      What am I missing? Whats the point?

      thanks in advance

        • 1. Re: adding record to CMR field
          ironbird

          As your method is only viewed on the remote interface, does the QuestionEntity a local interface of question ?
          I not, It can't work because you can only work with local interfaces on CMR getters and setters (It's the spec).

          • 2. Re: adding record to CMR field
            didi

            which method should have "both" interfaces: addQuestion or getQuestions?

            • 3. Re: adding record to CMR field
              ironbird

              It's doesn't matter (depends the client which calls theses methods. The major thing is that your QuestionEntity class is a local one. You cannot add or get remote interfaces of the QuestionEntity bean with a CMR getter and setter, no matter theses getter and setters are viewed locally or remotely.

              It means that the QuestionEntity class passed as parameter must have been created (or retreived) with its local home interface.

              • 4. Re: adding record to CMR field
                ironbird

                Also your relationship looks strange !

                @ejb:persistent-field
                @jboss:column-name name="questions"
                

                are tags for cmp fields. This means that you create both a CMR and a CMP field with the same name. I don't advise you to do that. I'm surprising you got no errors during deployment.
                Can you post your descriptors ?


                • 5. Re: adding record to CMR field
                  didi

                  everything is generated by xdoclet.

                  Here is jbosscmp-jdbc.xml:


                  <?xml version="1.0" encoding="UTF-8"?>
                  <!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 3.0//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_3_0.dtd">

                  <jbosscmp-jdbc>

                  java:/DefaultDS
                  <datasource-mapping>Hypersonic SQL</datasource-mapping>


                  <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 markup for those beans.
                  -->


                  <ejb-name>QuestionEntity</ejb-name>
                  <create-table>true</create-table>
                  <remove-table>true</remove-table>

                  <table-name>QuestionTable</table-name>

                  <cmp-field>
                  <field-name>id</field-name>
                  <column-name>id</column-name>

                  </cmp-field>
                  <cmp-field>
                  <field-name>headline</field-name>
                  <column-name>headline</column-name>

                  </cmp-field>
                  <cmp-field>
                  <field-name>description</field-name>
                  <column-name>description</column-name>

                  </cmp-field>
                  <cmp-field>
                  <field-name>answertype</field-name>
                  <column-name>answertype</column-name>

                  </cmp-field>
                  <cmp-field>
                  <field-name>answers</field-name>
                  <column-name>answers</column-name>

                  </cmp-field>




                  <ejb-name>LectureEntity</ejb-name>
                  <create-table>true</create-table>
                  <remove-table>true</remove-table>

                  <table-name>LectureTable</table-name>

                  <cmp-field>
                  <field-name>id</field-name>
                  <column-name>id</column-name>

                  </cmp-field>
                  <cmp-field>
                  <field-name>headline</field-name>
                  <column-name>headline</column-name>

                  </cmp-field>
                  <cmp-field>
                  <field-name>description</field-name>
                  <column-name>description</column-name>

                  </cmp-field>
                  <cmp-field>
                  <field-name>questions</field-name>
                  <column-name>questions</column-name>

                  </cmp-field>



                  </enterprise-beans>



                  <ejb-relation>
                  <ejb-relation-name>idLectureQuestion</ejb-relation-name>

                  <foreign-key-mapping/>

                  <ejb-relationship-role>
                  <ejb-relationship-role-name>each-lecture-has-a-lot-of-questions</ejb-relationship-role-name>
                  <key-fields>
                  <key-field>
                  <field-name>id</field-name>
                  <column-name>questions</column-name>
                  </key-field>
                  </key-fields>

                  </ejb-relationship-role>
                  <ejb-relationship-role>
                  <ejb-relationship-role-name>a-lot-of-questions-belong-to-one-lecture</ejb-relationship-role-name>
                  <key-fields/>

                  </ejb-relationship-role>
                  </ejb-relation>
                  <!--
                  To add jboss relationships for beans not managed by XDoclet, add
                  a file to your XDoclet merge directory called jbosscmp-jdbc-relationships.xml that contains
                  the <ejb-relation></ejb-relation> markups for those beans.
                  -->


                  </jbosscmp-jdbc>

                  • 6. Re: adding record to CMR field
                    didi

                    Here is ejb-jar.xml:

                    <?xml version="1.0" encoding="UTF-8"?>
                    <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">

                    <ejb-jar >

                    <![CDATA[No Description.]]>
                    <display-name>Generated by XDoclet</display-name>

                    <enterprise-beans>

                    <!-- Session Beans -->

                    <!--
                    To add session beans that you have deployment descriptor info for, add
                    a file to your XDoclet merge directory called session-beans.xml that contains
                    the markup for those beans.
                    -->

                    <!-- Entity Beans -->

                    <![CDATA[]]>
                    <display-name>Question Entity Bean</display-name>

                    <ejb-name>QuestionEntity</ejb-name>

                    de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.QuestionEntityHome
                    de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.QuestionEntity
                    <local-home>de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.QuestionEntityLocalHome</local-home>
                    de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.QuestionEntityLocal

                    <ejb-class>de.unimannheim.wifo3.cobana.ejb.prototype.entity.QuestionEntityCMP</ejb-class>
                    <persistence-type>Container</persistence-type>
                    <prim-key-class>de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.QuestionEntityPK</prim-key-class>
                    False
                    <cmp-version>2.x</cmp-version>
                    <abstract-schema-name>QuestionEntity</abstract-schema-name>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>id</field-name>
                    </cmp-field>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>headline</field-name>
                    </cmp-field>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>description</field-name>
                    </cmp-field>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>answertype</field-name>
                    </cmp-field>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>answers</field-name>
                    </cmp-field>


                    <query-method>
                    <method-name>findAll</method-name>
                    <method-params>
                    </method-params>
                    </query-method>
                    <ejb-ql><![CDATA[SELECT OBJECT(qe) FROM QuestionEntity qe]]></ejb-ql>


                    <query-method>
                    <method-name>findByAttributes</method-name>
                    <method-params>
                    <method-param>java.lang.String</method-param>
                    <method-param>java.lang.String</method-param>
                    <method-param>int</method-param>
                    <method-param>java.lang.Object</method-param>
                    </method-params>
                    </query-method>
                    <ejb-ql><![CDATA[SELECT OBJECT(qe) FROM QuestionEntity qe WHERE qe.headline = ?1 AND qe.description = ?2 AND qe.answertype = ?3]]></ejb-ql>

                    <!-- Write a file named ejb-finders-QuestionEntityBean.xml if you want to define extra finders. -->



                    <![CDATA[]]>
                    <display-name>Lecture Entity Bean</display-name>

                    <ejb-name>LectureEntity</ejb-name>

                    de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.LectureEntityHome
                    de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.LectureEntity
                    <local-home>de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.LectureEntityLocalHome</local-home>
                    de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.LectureEntityLocal

                    <ejb-class>de.unimannheim.wifo3.cobana.ejb.prototype.entity.LectureEntityCMP</ejb-class>
                    <persistence-type>Container</persistence-type>
                    <prim-key-class>de.unimannheim.wifo3.cobana.ejb.prototype.interfaces.LectureEntityPK</prim-key-class>
                    False
                    <cmp-version>2.x</cmp-version>
                    <abstract-schema-name>LectureEntity</abstract-schema-name>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>id</field-name>
                    </cmp-field>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>headline</field-name>
                    </cmp-field>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>description</field-name>
                    </cmp-field>
                    <cmp-field >
                    <![CDATA[]]>
                    <field-name>questions</field-name>
                    </cmp-field>


                    <query-method>
                    <method-name>findAll</method-name>
                    <method-params>
                    </method-params>
                    </query-method>
                    <ejb-ql><![CDATA[SELECT OBJECT(le) FROM LectureEntity le]]></ejb-ql>


                    <query-method>
                    <method-name>findByAttributes</method-name>
                    <method-params>
                    <method-param>java.lang.String</method-param>
                    <method-param>java.lang.String</method-param>
                    <method-param>java.util.Collection</method-param>
                    </method-params>
                    </query-method>
                    <ejb-ql><![CDATA[SELECT OBJECT(le) FROM LectureEntity le WHERE le.headline = ?1 AND le.description = ?2]]></ejb-ql>

                    <!-- Write a file named ejb-finders-LectureEntityBean.xml if you want to define extra finders. -->




                    <!--
                    To add entity beans that you have deployment descriptor info for, add
                    a file to your XDoclet merge directory called entity-beans.xml that contains
                    the markup for those beans.
                    -->

                    <!-- Message Driven Beans -->
                    <!--
                    To add message driven beans that you have deployment descriptor info for, add
                    a file to your XDoclet merge directory called message-driven-beans.xml that contains
                    the <message-driven></message-driven> markup for those beans.
                    -->

                    </enterprise-beans>

                    <!-- Relationships -->

                    <ejb-relation >
                    <ejb-relation-name>idLectureQuestion</ejb-relation-name>

                    <ejb-relationship-role >
                    <ejb-relationship-role-name>each-lecture-has-a-lot-of-questions</ejb-relationship-role-name>
                    One
                    <relationship-role-source >
                    <ejb-name>LectureEntity</ejb-name>
                    </relationship-role-source>
                    <cmr-field >
                    <cmr-field-name>questions</cmr-field-name>
                    <cmr-field-type>java.util.Collection</cmr-field-type>
                    </cmr-field>
                    </ejb-relationship-role>

                    <ejb-relationship-role >
                    <ejb-relationship-role-name>a-lot-of-questions-belong-to-one-lecture</ejb-relationship-role-name>
                    Many
                    <relationship-role-source >
                    <ejb-name>QuestionEntity</ejb-name>
                    </relationship-role-source>
                    </ejb-relationship-role>

                    </ejb-relation>
                    <!--
                    To add relationships for beans not managed by XDoclet, add
                    a file to your XDoclet merge directory called relationships.xml that contains
                    the <ejb-relation></ejb-relation> markups for those beans.
                    -->


                    <!-- Assembly Descriptor -->
                    <assembly-descriptor >
                    <!--
                    To add additional assembly descriptor info here, add a file to your
                    XDoclet merge directory called assembly-descriptor.xml that contains
                    the <assembly-descriptor></assembly-descriptor> markup.
                    -->

                    <!-- finder permissions -->

                    <!-- transactions -->
                    <container-transaction >

                    <ejb-name>QuestionEntity</ejb-name>
                    <method-name>*</method-name>

                    <trans-attribute>Required</trans-attribute>
                    </container-transaction>
                    <container-transaction >

                    <ejb-name>LectureEntity</ejb-name>
                    <method-name>*</method-name>

                    <trans-attribute>Required</trans-attribute>
                    </container-transaction>

                    <!-- finder transactions -->
                    </assembly-descriptor>

                    </ejb-jar>

                    • 7. Re: adding record to CMR field
                      didi

                      I am using j2sdk1.4.2_03/ and xdoclet-1.2.1/ but I am bound to jboss-3.0.7_jakarta-tomcat-4.1.24/

                      • 8. Re: adding record to CMR field
                        ironbird

                        As I say to you before, two bad things:

                        1) Your LectureEntity bean has a cmp field named questions, and a cmr field named also questions. Remove the tags I indicate before:

                        @ejb:persistent-field
                        @jboss:column-name name="questions"
                        

                        or rename one of them (cmp or cmr) and put the appropriate getter and setter.

                        2) The QuestionEntity (addQuestion parameter) is a remote interface. You cannot set a cmr field with a remote interface (only a local). For that, you have two solutions:
                        2.1 : retrieve a local interface from your client if you can and change your method:
                        public void addQuestion(QuestionEntityLocal question) {
                        this.getQuestions().add(question);
                        }
                        


                        2.2 : if you can't, just pass the primary key and retrieve a local interface in the method:
                        Add an ejb-ref to your bean:
                         * @ejb.ejb-ref
                         * ejb-name="QuestionEntity"
                         * view-type="local"
                        

                        Then in your method:
                        public void addQuestion(Long questionId) {
                        try {
                         javax.naming.Context ic = new InitialContext();
                         Object obj = ic.lookup(<Your Question bean JNDI name>);
                         // Something like "java:comp/env/ejb/QuestionEntityLocal"
                         QuestionEntityLocalHome Home = (QuestionEntityLocalHome)PortableRemoteObject.narrow(obj,QuestionEntityLocalHome.class);
                         QuestionEntityLocal question = Home.findByPrimaryKey(questionId);
                         this.getQuestions().add(question);
                        } catch(Exception e) {
                         // Error handling
                        }
                        }
                        



                        • 9. Re: adding record to CMR field
                          didi

                          may I send you an email with the LectureEntityBean.java? I am not getting it (I bet it is just a little, small thing..) even though I did everything you said

                          • 10. Re: adding record to CMR field
                            ironbird

                            My address is ironbirdy40 at yahoo dot com.
                            I rely on you not to be victim of spamming noise.
                            But what happens with the new code ? the same thing or errors ?
                            Put both entity beans, and the client, then I can test it in my computer.