4 Replies Latest reply on Nov 8, 2005 12:15 PM by danikenan

    composite pk with

    danikenan

      We have 3 tables clubtype, city and club.

      The pk of club is city_id and clubtype_id.

      
      club table
      
       *city_id | *clubtype_id | description
      -----------|--------------|------------
      
      
      city table
      
       *id | name
      ------|------
      
      
      clubtype table
      
       *id | name
      ------|------
      
      
      


      When trasformed to ejb3 with annotation, the three tables are entities and in order to express the fact that club has 2 columns as a primary key, i need a composite key.

      However, i did not find an example whre a composite key class has fields that are foreign keys. In the examples they are always simple types. Can it be done?

      Here is a simplified version of my code:


      
      @Embeddable(access = AccessType.FIELD)
      public class ClubPK{
      
       /*@ManyToOne - this is not enough, what to put here !!!*/
       private ClubType type;
      
       /*@ManyToOne - this is not enough, what to put here !!!*/
       private City city;
      
      }
      
      @Entity(access = AccessType.FIELD)
      public class Club {
      
       @Id(generate = GeneratorType.NONE)
       private ClubPK key;
      
       private String description;
      }
      
      @Entity(access = AccessType.FIELD)
      public class City {
      
       @Id(generate = GeneratorType.AUTO)
       private Long id;
      
       private String name;
      }
      
      
      @Entity(access = AccessType.FIELD)
      public class ClubType {
      
       @Id(generate = GeneratorType.AUTO)
       private Long id;
      
       private String name;
      }
      
      


      Please ignore any naming mismaches between the db and the java code. There is no real db. We use the auto schema generation feature of hibernate implementation so the problem does not lie in the naming of the fields/db columns.

      TIA

        • 1. Re: composite pk with
          heinrich

           

          (access = AccessType.FIELD)
          public class ClubPK{
          
           /* the pk fields */
           private Long clubTypeId;
           private Long cityId;
          
           @javax.persistence.Column(name = "club_type_id")
           public Long getClubTypeId() {
           return this.clubTypeId;
           }
          
           @javax.persistence.Column(name = "city_id")
           public Long getCityId() {
           return this.cityId;
           }
          
          }
          
          @Entity(access = AccessType.FIELD)
          public class Club {
          
           private ClubPK key;
           private String description;
          
           @javax.persistence.EmbeddedId
           public ClubPK getKey() {
           return this.key;
           }
          }
          
          @Entity(access = AccessType.FIELD)
          public class City {
          
          @Id(generate = GeneratorType.AUTO)
          private Long id;
          
          private String name;
          }
          
          
          @Entity(access = AccessType.FIELD)
          public class ClubType {
          
          @Id(generate = GeneratorType.AUTO)
          private Long id;
          
          private String name;
          }


          There is no need to put ManyToOne relations to the fields in the pk class.


          • 2. Re: composite pk with
            danikenan

            Thanks for the reply.


            If I use your solution, I lose the connection between the primary key and the entities it contains.

            If clubtype and city where not part of the pk I would not use a long field but rather the entitiy and the relation between the long id and the entity whould have been automatically infered by the orm framework.

            Why the fact that a forign key is also part of a primary key changes the way it is mapped?

            Also, I loose all the benefits of ORM and return to use the relational model as well as loose the information hiding and decoupling from the underlying schema.

            • 3. Re: composite pk with
              heinrich

              Ok, i'm sorry. I forgot something. The club class must also contain two fields for the city and clubtype objects.

              (access = AccessType.FIELD)
              public class ClubPK{
              
               /* the pk fields */
               private Long clubTypeId;
               private Long cityId;
              
               @javax.persistence.Column(name = "club_type_id")
               public Long getClubTypeId() {
               return this.clubTypeId;
               }
              
               @javax.persistence.Column(name = "city_id")
               public Long getCityId() {
               return this.cityId;
               }
              
              }
              
              @Entity(access = AccessType.FIELD)
              public class Club {
              
               private ClubPK key;
               private String description;
              
               private City city;
               private ClubType clubType;
              
               @javax.persistence.EmbeddedId
               public ClubPK getKey() {
               return this.key;
               }
              
               [...]
              
               @javax.persistence.ManyToOne(fetch=FetchType.LAZY)
               @javax.persistence.JoinColumn(name = "city_id", insertable=false, updatable=false)
               public City getCity() {
               return this.city;
               }
               public void setCity (City city) {
               this.city = city;
               }
               [...] and so on
              
              }
              
              @Entity(access = AccessType.FIELD)
              public class City {
              
              @Id(generate = GeneratorType.AUTO)
              private Long id;
              
              private String name;
              }
              
              
              @Entity(access = AccessType.FIELD)
              public class ClubType {
              
              @Id(generate = GeneratorType.AUTO)
              private Long id;
              
              private String name;
              }
              



              Hope this is complete now =)

              • 4. Re: composite pk with
                danikenan

                Thanks a lot for you help. You solved my problem.