5 Replies Latest reply on Aug 2, 2005 5:27 PM by Jorge Tello

    Composite Key / Foreign Key EJB3

    Konstantinos Kostarellis Newbie

      I know there was some discussion about this b4. I have looked @ them and the ejb3 public review spec + theHibernate Annotations Reference Guide but I could not solve / figure out the solution for my prob.

      I'm using PostgreSQL 8.0.3 + JBoss AS 4.0.3RC1 of the install-jar-file.

      The Problem:
      I got an Entity Person
      usuall attribute (name etc. etc. ) and the column (person_id) as primkey identifier. works fine ... (had it running with an OneTwoMany relation Set but that does not matter here anyways)

      So I want to use EJB3.0 Annotations for getting the following done:

      I have created an Entity Personrelationship with the following fields.

      private Person person;

      private Person relperson;

      private String personrelshipcd;

      At the getters of the Person Methods i have put in the following Annotations
      @ManyToOne
      @JoinColumn(name = "person_id")

      and @ the class level i have put in following @Table Annotation
      @Table(name = "personrelationship", uniqueConstraints={@UniqueConstraint(columnNames={"person","relperson"})})

      in the hope i would declare those two fields as the Composite Primarykey out of the 2 foreign keys ...

      somebody who knows what to do ?

      thnx in advance :)

        • 1. Re: Composite Key / Foreign Key EJB3
          Jeff Schnitzer Newbie

          This is what works for me. I have Person, Question, and Response (pk is personid, questionid).

          @Embeddable(access=AccessType.FIELD)
          public class ResponsePK implements java.io.Serializable
          {
           /** */
           Long personId;
           Long questionId;
          


          and...

          @Entity(access=AccessType.FIELD)
          @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
          public class Response implements java.io.Serializable
          {
           /** */
           @Id(generate=GeneratorType.NONE)
           ResponsePK pk;
          
           @Column(nullable=false)
           float answer;
          
           @Column(nullable=false)
           Date changed;
          
           /** Note this "overlaps" with the PK */
           @ManyToOne
           @JoinColumn(name="personId", insertable=false, updatable=false)
           Person person;
          
           /** Note this "overlaps" with the PK */
           @ManyToOne
           @JoinColumn(name="questionId", insertable=false, updatable=false)
           Question question;
          


          Should be fairly self-explanatory.

          Jeff Schnitzer
          http://www.similarity.net

          • 2. Re: Composite Key / Foreign Key EJB3
            Konstantinos Kostarellis Newbie

            unfortunatly this did not do the trick ...

            i added "@Embeddable(access=AccessType.FIELD)" in the Person entity

            and adjusted the Personrelationship to look like this:

            @Entity(access=AccessType.FIELD)
            @Table(name = "person_Relationship")
            @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
            public class Personrelationship implements Serializable {
            
             // Fields
             private Person person;
             private Person relperson;
             private String personrelshipcd;
            
             // Property accessors
            
             /**
             * @return Returns the person.
             */
             @ManyToOne
             @JoinColumn(name = "person_id", insertable=false, updatable=false)
             public Person getPerson() {
             return person;
             }
            
             /**
             * @param person
             * The person to set.
             */
             public void setPerson(Person person) {
             this.person = person;
             }
            
             /**
             * @return Returns the relperson.
             */
             @ManyToOne
             @JoinColumn(name = "person_id", insertable=false, updatable=false)
             public Person getRelperson() {
             return relperson;
             }
            
             /**
             * @param relperson
             * The relperson to set.
             */
             public void setRelperson(Person relperson) {
             this.relperson = relperson;
             }
            
            
             /**
             * @return Returns the personrelshipcd.
             */
             @Column(name = "Person_relship_cd", length = 40, nullable = false)
             public String getPersonrelshipcd() {
             return personrelshipcd;
             }
            
             /**
             * @param personrelshipcd
             * The personrelshipcd to set.
             */
             public void setPersonrelshipcd(String personrelshipcd) {
             this.personrelshipcd = personrelshipcd;
             }
            
            }
            
            



            unfortunatly i still get a
            org.hibernate.AnnotationException: No identifier specified for entity: Personrelationship
            on deployment.

            The point is that I want to make an Entity that obviously holds an Relationship between two Persons (same classtype) in the Database.

            this Relationship is uniquely identified and adequately described throu its
            person and relperson (primary key/forein key) entry.

            So the point is how to make them the composite key of the table..

            as i saw in your code example you had an addtional Primkey field
             @Id(generate=GeneratorType.NONE)
             ResponsePK pk;
            


            I was trying to avoid that cause its not needed.
            So I don't know how to do this with EJB3.0 annotation.

            thankfull for any suggestions


            • 3. Re: Composite Key / Foreign Key EJB3
              Jeff Schnitzer Newbie

              The @Id field is needed. There won't be extra DB columns.

              The @Id field (composite primary key) is what creates the id columns for personA and personB.

              The (insertable=false, updatable=false) on the Person fields in your Personrelationship, combined with the column name overlap with the PK, means that while Hibernate will create the associated objects, there is no extra pollution of the DB data model.

              Make sense?

              Just a nit... but it wouldn't hurt to follow java-standard capitalization conventions, especially when random people on message boards have to read your code.

              Jeff Schnitzer
              http://www.similarity.net

              • 4. Re: Composite Key / Foreign Key EJB3
                Konstantinos Kostarellis Newbie

                yes I'm sorry about violating the java-standard capitalization conventions, you are right about that ... I changed everything for that matter ... If you like i can repost (hopefully i did good)... I guess its not that important thou

                thnx for your help again ... I had oversighted you putting the @Embendable in the PK class not in the "Person" - Entity. Works fine now. thnx a lot

                • 5. Re: Composite Key / Foreign Key EJB3
                  Jorge Tello Newbie

                  Hi,

                  My problem is:

                  I got an Entity RolProcTrans (pk is codProceso, codTrans,tipoRol).

                  @Entity
                  @Table(name = "ROL_PROC_TRANS")
                  public class RolProcTrans implements Serializable {
                   private RolProcTransPK pk;
                   private RolTransaccion1 rolTransaccion1;
                  
                   @ManyToOne
                   @JoinColumns( {
                   @JoinColumn(name = "COD_TRANS", insertable = false, updatable = false),
                   @JoinColumn(name = "TIPO_ROL", insertable = false, updatable = false) })
                   public RolTransaccion1 getRolTransaccion1() {
                   return rolTransaccion1;
                   }
                  
                   public void setRolTransaccion1(RolTransaccion1 rolTransaccion1) {
                   this.rolTransaccion1 = rolTransaccion1;
                   }
                  
                   @Id(generate=GeneratorType.NONE)
                   public RolProcTransPK getPk() {
                   return pk;
                   }
                  
                   public void setPk(RolProcTransPK pk) {
                   this.pk = pk;
                   }
                  }

                  the pk class is:
                  @Embeddable
                  public class RolProcTransPK implements Serializable {
                   private Long codProceso;
                   private String codTrans;
                   private Integer tipoRol;
                  ...

                  and Entity RolTransaccion1

                  @Entity
                  @Table(name = "ROL_TRANSACCION_1")
                  public class RolTransaccion1 implements Serializable {
                   private String codEmpresa;
                   private RolTransaccion1PK pk;
                   private List<RolProcTrans> rolesProcTrans;
                  
                   @OneToMany(fetch = FetchType.LAZY, mappedBy = "rolTransaccion1")
                   public List<RolProcTrans> getRolesProcTrans() {
                   return rolesProcTrans;
                   }
                  
                   public void setRolesProcTrans(List<RolProcTrans> rolesProcTrans) {
                   this.rolesProcTrans = rolesProcTrans;
                   }
                  
                   @Column(name = "COD_EMPRESA")
                   public String getCodEmpresa() {
                   return codEmpresa;
                   }
                  
                   public void setCodEmpresa(String codEmpresa) {
                   this.codEmpresa = codEmpresa;
                   }
                  
                   @Id(generate=GeneratorType.NONE)
                   public RolTransaccion1PK getPk() {
                   return pk;
                   }
                  
                   public void setPk(RolTransaccion1PK pk) {
                   this.pk = pk;
                   }
                  }

                  pk class

                  @Embeddable
                  public class RolTransaccion1PK implements Serializable {
                   private String codTrans;
                   private Integer tipoRol;
                  ...


                  I´m use SQL Server 2000 SP3.
                  When I try list RolProcTrans Entity
                  the error is:

                  16:13:38,623 ERROR [JDBCExceptionReporter] [Microsoft][SQLServer 2000 Driver for JDBC]Value can not be converted to requested type.

                  I try, remove @ManyToOne relation and this function correctly

                  What Happend?

                  pleace some Idea.

                  Thank you very much