1 2 Previous Next 24 Replies Latest reply on Jun 18, 2004 3:26 AM by aloubyansky

    Unknown-PK Problems...

    karstents

      Hi folks,

      I'm trying to get an CMP EntityBean startet that should have an auto-generated primary-key, an auto-incremented Integer.
      After searching quite a long time for information about this, I found only little. And it's not working.

      I'd strongly apreciate some help, or maybe even some links/books/whatever where I can get more information.

      I'm working with Eclipse 2.1.3; JBoss 3.2.3; XDoclet and MySQL.
      Here are my XMLs...

      Thanks in advance for your help.
      Karsten

      ejb-jar.xml

       <entity >
       <description><![CDATA[The Employee Entity Bean saves every Employee.]]></description>
       <display-name>EB_Employee</display-name>
       <ejb-name>Employee</ejb-name>
       <local-home>medsched.entity.employee.EmployeeLocalHome</local-home>
       <local>medsched.entity.employee.EmployeeLocal</local>
       <ejb-class>medsched.entity.employee.EmployeeBean</ejb-class>
       <persistence-type>Container</persistence-type>
       <prim-key-class>java.lang.Object</prim-key-class>
       <reentrant>false</reentrant>
       <cmp-version>2.x</cmp-version>
       <abstract-schema-name>Employee</abstract-schema-name>
       <cmp-field >
       <field-name>firstname</field-name>
       </cmp-field>
       <cmp-field >
       <field-name>lastname</field-name>
       </cmp-field>
       <cmp-field >
       <field-name>telephone</field-name>
       </cmp-field>
       </entity>
      


      jbosscmp-jdbc.xml
       <entity>
       <ejb-name>Employee</ejb-name>
       <create-table>true</create-table>
       <remove-table>true</remove-table>
       <cmp-field>
       <field-name>firstname</field-name>
       <column-name>firstname</column-name>
       </cmp-field>
       <cmp-field>
       <field-name>lastname</field-name>
       <column-name>lastname</column-name>
       </cmp-field>
       <cmp-field>
       <field-name>telephone</field-name>
       <column-name>telephone</column-name>
       </cmp-field>
       <unknown-pk>
       <unknown-pk-class>java.lang.Integer</unknown-pk-class>
       <field-name>employeeID</field-name>
       <read-only>true</read-only>
       <column-name>employeeid</column-name>
       <auto-increment/>
       </unknown-pk>
       </entity>
      


        • 1. Re: Unknown-PK Problems...
          sesques

          Hi,

          You are missing a <entity-command name> tag in your jbosscmp-jdbc.xml.

          This tag is database dependent (used to get the last generated primary key. For MSSQL, you must set
          <entity-command name="mssql-fetch-key" />

          • 2. Re: Unknown-PK Problems...
            sesques

            For MySQL,

            you mus set
            <entity-command name="mysql-get-generated-keys" />

            • 3. Re: Unknown-PK Problems...
              mpforste

              I do have it - in the defaults section
              <entity-command name="mysql-get-generated-keys"
              class="org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCMySQLCreateCommand"/>

              • 4. Re: Unknown-PK Problems...
                mpforste

                And btw The Primary key is working correctly without using the Unknown-PK We are using the
                mysql-connector-java-3.1.1-alpha-bin.jar

                and configuring the settings as follows

                <ejb-name>TransTypeBean</ejb-name>
                <table-name>trans_type</table-name>
                <cmp-field>
                <field-name>Id</field-name>
                <column-name>id</column-name>
                <not-null/>
                <auto-increment/>
                </cmp-field>
                <cmp-field>
                <field-name>Description</field-name>
                <column-name>tt_desc</column-name>
                <jdbc-type>VARCHAR</jdbc-type>
                <sql-type>VARCHAR(50)</sql-type>
                </cmp-field>



                • 5. Re: Unknown-PK Problems...
                  sesques

                  Hi,

                  So, is your problem solved ?
                  I really don't understand how you can make a database generated key without an unknown primary key. I don't know mySQL, just Oracle and MSSQL, and I have many projecs working with database generated keys using the unknown-pk.

                  Are you sure it is the database which generates the key, or Jboss itself ?
                  PS: Same problem with your Transaction bean.

                  Another thing: Your foreign key (in Transaction bean) is marqued as NOT NULL. I experiment myself that Jboss cannot delay the insert after ejbPostCreate when the database generates the key. This is a problem because CMR fields can only be set in ejbPostCreate. This problem is described in many forums.
                  So the solution is to create an additionnal CMP field for the foreign key, then you can set a value in ejbCreate (a good one of course), and then sets the CMR field in ejbPostCreate.

                  • 6. Re: Unknown-PK Problems...
                    karstents

                    Yes, it works perfect by now. Well, in fact, I do have some ForeignKey Problems, but that's a different story... ;)

                    This is the solution:
                    ejb-jar.xml

                     <entity >
                     <description><![CDATA[The Employee Entity Bean saves every Employee.]]></description>
                     <display-name>EB_DataBase - Employee: Employee</display-name>
                     <ejb-name>Employee</ejb-name>
                     <local-home>medsched.entity.employee.EmployeeLocalHome</local-home>
                     <local>medsched.entity.employee.EmployeeLocal</local>
                     <ejb-class>medsched.entity.employee.EmployeeBean</ejb-class>
                     <persistence-type>Container</persistence-type>
                     <prim-key-class>java.lang.Integer</prim-key-class>
                     <reentrant>false</reentrant>
                     <cmp-version>2.x</cmp-version>
                     <abstract-schema-name>Employee</abstract-schema-name>
                     <cmp-field >
                     <field-name>employeeID</field-name>
                     </cmp-field>
                     <cmp-field >
                     <field-name>firstname</field-name>
                     </cmp-field>
                     <cmp-field >
                     <field-name>lastname</field-name>
                     </cmp-field>
                     <cmp-field >
                     <field-name>telephone</field-name>
                     </cmp-field>
                     <primkey-field>employeeID</primkey-field>
                     </entity>
                    


                    jbosscmp-jdbc.xml
                     <entity>
                     <ejb-name>Employee</ejb-name>
                     <datasource>java:/mySQLDS</datasource>
                     <datasource-mapping>mySQL</datasource-mapping>
                     <create-table>true</create-table>
                     <remove-table>false</remove-table>
                     <cmp-field>
                     <field-name>employeeID</field-name>
                     <column-name>employeeid</column-name>
                     <auto-increment/>
                     </cmp-field>
                     <cmp-field>
                     <field-name>firstname</field-name>
                     <column-name>firstname</column-name>
                     </cmp-field>
                     <cmp-field>
                     <field-name>lastname</field-name>
                     <column-name>lastname</column-name>
                     </cmp-field>
                     <cmp-field>
                     <field-name>telephone</field-name>
                     <column-name>telephone</column-name>
                     </cmp-field>
                     <unknown-pk>
                     <unknown-pk-class>java.lang.Integer</unknown-pk-class>
                     <column-name>employeeid</column-name>
                     <jdbc-type>INTEGER</jdbc-type>
                     <sql-type>INTEGER</sql-type>
                     <auto-increment/>
                     </unknown-pk>
                     <entity-command name="mysql-get-generated-keys">
                     </entity-command>
                     </entity>
                    


                    I could post the XDoclet Tags, if anyone interested.
                    However, thanks for all your help!

                    • 7. Re: Unknown-PK Problems...
                      sesques

                      Normally, when the key is auto-generated byt the database,
                      the prim-key-class should be java.lang.Object without declaring the primkey-field (like in your first version of ejb-jar.xml)

                      + No getters and setters defined on the CMP field employeeID (because you must use the findbyPrimaryKey method on the home interface or getPrimaryKey on the bean.

                      + the return type of ejbCreate must be java.lang.Object.

                      • 8. Re: Unknown-PK Problems...
                        karstents

                        That are good points.
                        In fact, now that you tell it, I remember to have read the object things and am now wondering, why this works. Well, it does. Even though the ejbCreate is Integer. Strange...

                        I had an error, with not declaring a pk-field, or having a pk-field declared, which is no cmp-field. JBoss didn't like that.

                        Is my working version more of a bug?
                        Here's my EmployeeBean.java

                        /**
                         * The Employee Entity Bean handles the information of an employee.
                         * @author Karsten Jahn (OrangeOak)
                         * @version 1.0
                         *
                         * @ejb.bean
                         * name = "Employee"
                         * display-name = "EB_DataBase - Employee: Employee"
                         * description = "The Employee Entity Bean saves every Employee."
                         * view-type = "local"
                         * type = "CMP"
                         * cmp-version = "2.x"
                         * local-jndi-name = "ejb/medsched/employee/Employee"
                         * reentrant = "false"
                         * primkey-field = "employeeID"
                         *
                         * @ejb.pk class = "java.lang.Object"
                         *
                         * @jboss.persistence
                         * create-table = "true"
                         * remove-table = "false"
                         * datasource = "java:/mySQLDS"
                         * datasource-mapping = "mySQL"
                         * table-name = "employee"
                         *
                         * @jboss.unknown-pk
                         * class = "java.lang.Integer"
                         * auto-increment = "true"
                         * column-name = "employeeid"
                         * sql-type = "INTEGER"
                         * jdbc-type = "INTEGER"
                         *
                         * @jboss.entity-command name = "mysql-get-generated-keys"
                         */
                        public abstract class EmployeeBean implements EntityBean {
                        
                         /**
                         * @ejb.interface-method view-type = "local"
                         * @ejb.persistence column-name = "employeeid"
                         * @ejb.pk-field
                         * @jboss.persistence
                         * auto-increment = "true"
                         * not-null = "true"
                         */
                         public abstract Integer getEmployeeID();
                         public abstract void setEmployeeID(Integer employeeID);
                        
                        [...]
                        
                         /**
                         * @throws CreateException
                         * @ejb.create-method
                         */
                         public Integer ejbCreate(StaffMember employee) throws CreateException {
                         setLastname(employee.lastname);
                         setFirstname(employee.firstname);
                         setTelephone(employee.telephone);
                         return null;
                         }
                         public void ejbPostCreate(StaffMember employee) {
                         }
                        }
                        


                        • 9. Re: Unknown-PK Problems...
                          sesques

                          Normally, this should work and is compliant wth the EJB spec.
                          (But if not, keep your version as well, it will be a software mystery ;-)

                          /**
                           * The Employee Entity Bean handles the information of an employee.
                           * @author Karsten Jahn (OrangeOak)
                           * @version 1.0
                           *
                           * @ejb.bean
                           * name = "Employee"
                           * display-name = "EB_DataBase - Employee: Employee"
                           * description = "The Employee Entity Bean saves every Employee."
                           * view-type = "local"
                           * type = "CMP"
                           * cmp-version = "2.x"
                           * local-jndi-name = "ejb/medsched/employee/Employee"
                           * reentrant = "false"
                           *
                           * @ejb.pk class = "java.lang.Object"
                           *
                           * @jboss.persistence
                           * create-table = "true"
                           * remove-table = "false"
                           * datasource = "java:/mySQLDS"
                           * datasource-mapping = "mySQL"
                           * table-name = "employee"
                           *
                           * @jboss.unknown-pk
                           * class = "java.lang.Integer"
                           * auto-increment = "true"
                           * column-name = "employeeid"
                           * field-name="employeeID"
                           * sql-type = "INTEGER"
                           * jdbc-type = "INTEGER"
                           *
                           * @jboss.entity-command name = "mysql-get-generated-keys"
                           */
                          public abstract class EmployeeBean implements EntityBean {
                          
                          [...]
                          
                           /**
                           * @throws CreateException
                           * @ejb.create-method
                           */
                           public java.lang.Object ejbCreate(StaffMember employee) throws CreateException {
                           setLastname(employee.lastname);
                           setFirstname(employee.firstname);
                           setTelephone(employee.telephone);
                           return null;
                           }
                           public void ejbPostCreate(StaffMember employee) {
                           }
                          }
                          



                          • 10. Re: Unknown-PK Problems...
                            karstents

                            Well... what can I say... this works perfectly as well... thank you very much!
                            Being within the EJB spec is a bit more sedative. ;)

                            • 11. Re: Unknown-PK Problems... with XDoclet and CMR
                              hxp

                              Hi --

                              Has anybody noticed Unknown-PK Problems, with XDoclet and _CMR_?

                              Are there known-bugs regarding CMR interaction with Unknown-PK that have already been posted against JBoss3.2.3?

                              Anybody know of relevant forum/wiki URLs?

                              Or... has anybody gotten Unknown-PK going with XDoclet and _CMR_, such that successful build, deployment, and runtime behavior is proper with both MySQL and HSQL?


                              Thanks!

                              --Howard

                              • 12. Re: Unknown-PK Problems...
                                sesques

                                Unknow-pk got nothing to do with CMR fields ????

                                • 13. Re: Unknown-PK Problems...
                                  hxp

                                  Yes, CMR and unknown-pk are distinct concepts, but .... they could interact in practice because CMR creates foreign key relationships and thus uses the pk of the entity at the other end of the relationship.

                                  • 14. Re: Unknown-PK Problems...
                                    hxp

                                    Sesques --

                                    I've tried quite a number of different variations on the xdoclet tags, and each variation has its problems. Here are some samples of what seem to be perverse interactions between CMR and unknownpk:

                                    00:40:52,984 INFO [EjbModule] Deploying FaqCategoryEJB
                                    00:40:52,984 INFO [EjbModule] Deploying FaqEJB
                                    00:40:53,000 INFO [FaqModule] Creating
                                    00:40:53,000 INFO [FaqModule] Created
                                    00:40:53,140 ERROR [EntityContainer] Starting failed
                                    org.jboss.deployment.DeploymentException:
                                    Role: faq-has-faqCategory with multiplicity many
                                    using foreign-key mapping is not allowed to have key-fields
                                    at
                                    org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationshipRoleMetaData.loadKeyFields
                                    (JDBCRelationshipRoleMetaData.java:415)
                                    at
                                    org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationshipRoleMetaData.init
                                    (JDBCRelationshipRoleMetaData.java:188)
                                    at
                                    org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationMetaData.<init>
                                    (JDBCRelationMetaData.java:339)...




                                    15:15:47,640 ERROR [EntityContainer] Starting failed
                                    org.jboss.deployment.DeploymentException:
                                    Role 'faqCategory-has-faqs' on Entity Bean 'FaqCategoryEJB' :
                                    CMP field for key not found: field name='id'
                                    at
                                    org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationshipRoleMetaData.loadKeyFields
                                    (JDBCRelationshipRoleMetaData.java:432)
                                    at
                                    org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationshipRoleMetaData.init
                                    (JDBCRelationshipRoleMetaData.java:188)....



                                    15:39:29,328 ERROR [EntityContainer] Starting failed
                                    org.jboss.deployment.DeploymentException:
                                    At least one role of a foreign-key mapped relationship must have key fields
                                    (or <primkey-field> is missing from ejb-jar .xml):
                                    ejb-relation-name=Faq-FaqCategory
                                    at
                                    org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationMetaData.<init>
                                    (JDBCRelationMetaData.java:347)...


                                    I am working on a proof-of-concept for migrating the backend of JBossNukes to a pure-CMP/pure-CMR architecture. Currently, Nukes uses entity EJBs merely for selects and updates; it uses lots of database-dependent DDL to create, initialize, and drop the tables :-( !! How can we call this Nukes on JBoss ?? The installation process is at least triple as complex as it needs to be; take a glance at my wiki about installing Nukes at:

                                    http://jboss.org/wiki/Wiki.jsp?page=InstallUninstallUpgrade

                                    A pure-CMP approach would simplify installation greatly and allow us to gain a much larger user & contributor base.


                                    I am working on architecting a complete overhaul of this backend aspect of Nukes. Even though I haven't posted my main materials yet, you can see some of my preliminary posts on this subject:

                                    http://www.jboss.org/index.html?module=bb&op=viewtopic&t=45576

                                    And the last 3 posts of:
                                    http://www.jboss.org/index.html?module=bb&op=viewtopic&t=44058


                                    The fruits of my effort will all be contributed to JBossNukes as a set of templates for migrating all the modules. During the next few days, I will be starting several wikis and forum threads on these subjects, but I really would like to have a clean proof-of-concept to launch the discussions. My other unknown-pk entities, having no CMR, work fine.... but I need to show CMR working in order to show that this approach is ready for prime time.

                                    So my initial post was to find out if there are well-known bugs in xdoclet's CMR or unknown-pk code generation, or in JBossCMP's implementation of CMR with unknown-pk.

                                    If you want me to post the dozen+ variations of code that I have tried, I'll pull that together and post em... but first, perhaps there is a simple answer that I am ignorant of or overlooking...

                                    Or perhaps somebody has something similar to the code already posted on this thread, but with CMR xdoclet tagging... it would be great if you could post a sample of working entity ejb code which contains xdoclet tags for unknown-pk, as well as xdoclet tags for at least one CMR field? Such as 2 related entities, each using unknown-pk for its own PK, and each having a CMR field for its relation with the other entity?

                                    -- Howard

                                    1 2 Previous Next