4 Replies Latest reply on Apr 2, 2005 8:09 PM by websel

    Problem with simple 1-to-1 Relation with xdoclet and unknown

    stud

      Hello everyone,
      i'm desperatly trying to write a simple CMR between two Entity Beans using XDoclet and the additional challenge of using unkown primary keys :)

      I have two beans, a User and a Folder bean. Every User has a folder but not every Folder belongs to a user.

      My code so far:

      UserBean.java

      /**
       * @ejb.bean
       * name = "User"
       * schema = "UserSchema"
       * jndi-name = "User";
       * description = "A User Bean"
       * type = "CMP"
       * cmp-version = "2.x"
       * @ejb.pk
       * class = "java.lang.Object"
       * generate = "false"
       * ---
       * @jboss.unknown-pk
       * class = "java.lang.Integer"
       * column-name = "user_id"
       * auto-increment = "true"
       * sql-type = "INTEGER"
       * jdbc-type = "INTEGER"
       * @jboss.persistence
       * pk-constraint = "false"
       * remove-table = "true"
       * @jboss.entity-command
       * name = "hsqldb-fetch-key"
       */
      public abstract class UserBean implements EntityBean {
       ...
       /**
       * @ejb.interface-method
       * @ejb.relation
       * name = "USER-has-one-FOLDER"
       * role-name = "Every USER has one FOLDER"
       * target-ejb = "Folder"
       * target-role-name = "Some FOLDER belong to a USER"
       * target-cascade-delete = "yes"
       * ---
       * @jboss.relation
       * related-pk-field = "folder"
       * fk-column = "folder_id"
       * dbindex = "true"
       *
       */
       public abstract Folder getFolder();
      }


      Folder.java
      /**
       * @ejb.bean
       * name = "Folder"
       * schema = "FolderSchema"
       * jndi-name = "Folder";
       * description = "A Folder Bean"
       * type = "CMP"
       * cmp-version = "2.x"
       * @ejb.pk
       * class = "java.lang.Object"
       * generate = "false"
       * ---
       * @jboss.unknown-pk
       * class = "java.lang.Integer"
       * column-name = "folder_id"
       * auto-increment = "true"
       * sql-type = "INTEGER"
       * jdbc-type = "INTEGER"
       * @jboss.persistence
       * pk-constraint = "false"
       * remove-table = "true"
       * @jboss.entity-command
       * name = "hsqldb-fetch-key"
       */
      public abstract class FolderBean implements EntityBean {
       ... (nothing specific to the relation)
      }


      This however gives me a DeploymentException:

      Role 'Some FOLDER belong to a USER' on Entity Bean 'Folder' : CMP field for key not found: field name='folder_id'


      I assume because of me using an unknown primary key its field is not a normal CMP field or something...
      Is there a way to work around this?

      Does anyone know more?
      Thanks for the help,
      Stud

        • 1. Re: Problem with simple 1-to-1 Relation with xdoclet and unk
          stud

          Perhaps I should downsize my question for a start:

          Is it possible to do a CM relation on an unknown primary key in JBoss?

          Unknown primary Keys being the ones mentioned in the EJB 2.0 Spec in section 10.8.3
          Xdoclet code would still be nice :)

          • 2. Re: Problem with simple 1-to-1 Relation with xdoclet and unk

            You need to add cmp getter and setter methods and tags for the primary key fields.

            For example on the UserBean:

            /**
             *
             * @ejb.persistent-field
             * @ejb.persistence
             * column-name="user_id"
             * jdbc-type="INTEGER"
             * sql-type="INTEGER"
             * @ejb.pk-field
             * @ejb.interface-method
             * @jboss.persistence
             * auto-increment="true"
             */
             public abstract java.lang.Integer getUserId();
            
            /**
             *
             * @ejb.interface-method
             */
             public abstract void setUserId(java.lang.Integer userId);
            


            Not all of those tags may be necessary, but those are the tags that I have.
            You also might need at least one ejbCreate method.

            Hope this helps,
            Mark

            • 3. Re: Problem with simple 1-to-1 Relation with xdoclet and unk
              websel

              Sounds reasonable however something during compiling with Java 5.0 the compilation of the related value object blows up :-(

              [javac] C:\opt\eclipse\workspace\test\build\generate\test\ejb\value\PersonValue.java:80: Object() in java.lang.Object cannot be applied to (java.lang.Integer)
              [javac] pk = new java.lang.Object(this.getId());


               /**
              * @ejb.bean
              * name="Person"
              * display-name = "PersonEB"
              * description = "Client and Employee humans table"
              * type="CMP"
              * cmp-version="2.x"
              * jndi-name="ejb/test/Person"
              * local-jndi-name="ejb/test/PersonLocal"
              * view-type = "local"
              *
              * @ejb.pk
              * class = "java.lang.Object"
              * generate = "false"
              * ---
              * @jboss.unknown-pk
              * class = "java.lang.Integer"
              * column-name = "id"
              * auto-increment = "true"
              * sql-type = "INTEGER"
              * jdbc-type = "INTEGER"
              *
              * @jboss.persistence
              * table-name="person"
              * read-only = "false"
              * create-table = "false"
              * remove-table = "false"
              * pk-constraint = "false"
              *
              * @jboss.entity-command
              * name="postgresql-fetch-seq"
              * class="org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCPostgreSQLCreateCommand"
              *
              * @ejb.finder
              * method-intf="LocalHome"
              * query="SELECT OBJECT(o) FROM Person o"
              * result-type-mapping="Local"
              * signature="java.util.Collection findAll()"
              *
              * @ejb.value-object
              * match="*"
              * name="Person"
              *
              */
              
              public abstract class PersonBean extends BaseEntityBean implements EntityBean {
              
               /**
               * @ejb.persistence-field
               * @ejb.persistence
               * column-name="id"
               * jdbc-type="INTEGER"
               * sql-type="INTEGER"
               * @ejb.pk-field
               * @ejb.interface-method
               * @jboss.persistence
               * auto-increment = "true"
               */
               public abstract java.lang.Integer getId();
              
               /**
               * @ejb.interface-method
               */
               public abstract void setId(java.lang.Integer id);
              
              Removing the VO from the code has it compiles correctly however that does not sound like an ok solution to me :-)
              
              Any hints what i'm forgetting here? Many thanks in advance.
              
              Wessel de Roode
              


              • 4. Re: Problem with simple 1-to-1 Relation with xdoclet and unk
                websel

                Got it fixed!

                The trick is to declare the primary key in the @ejb.bean tag. and set the correct object-specs like Integer

                /**
                * @ejb.bean
                * name="Address"
                * display-name = "AddressEB"
                * description = "adres tabel"
                * type="CMP"
                * cmp-version="2.x"
                * jndi-name="ejb/test/Address"
                * local-jndi-name="ejb/test/AddressLocal"
                * view-type = "local"
                * primkey-field = "id"
                
                *
                * @ejb.pk
                * class = "java.lang.Integer"
                * generate = "false"
                *
                *
                * @jboss.persistence
                * table-name="address"
                * read-only = "false"
                * create-table = "false"
                * remove-table = "false"
                * pk-constraint = "false"
                *
                * @jboss.entity-command
                * name="postgresql-fetch-seq"
                * class="org.jboss.ejb.plugins.cmp.jdbc.keygen.JDBCPostgreSQLCreateCommand"
                *
                * @jboss.unknown-pk
                * auto-increment = "true"
                * column-name = "id"
                * jdbc-type = "BIGINT"
                * sql-type = "SERIAL"
                * class = "java.lang.Object"
                *
                * @ejb.finder
                * method-intf="LocalHome"
                * query="SELECT OBJECT(o) FROM Address o"
                * result-type-mapping="Local"
                * signature="java.util.Collection findAll()"
                *
                *
                * @ejb.value-object
                * match="*"
                * name="Address"
                *
                */
                
                public abstract class AddressBean extends BaseEntityBean implements EntityBean {
                
                 /**
                 * @ejb.pk-field
                 * @ejb.interface-method
                 * @ejb.persistence
                 * @jboss.persistence
                 * auto-increment = "true"
                 */
                 public abstract Integer getId();
                .......
                

                Now it has a clean compile and deployment.
                Tomorrow i'll check out if CMR is working also..

                Wesssel de Roode