persistence@glassfish.java.net

RE: JoinColumn of relationship with subclasses which has joined strategy?

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Thu, 16 Nov 2006 10:20:03 -0500

Hello Wonseok,
    Either case should work in TopLink. I am not sure there is a "correct" way but I would expect customers to do either but most often reference the column of the subclass table. What is not working?
--Gordon
  -----Original Message-----
  From: Wonseok Kim [mailto:guruwons_at_gmail.com]
  Sent: Thursday, November 16, 2006 7:24 AM
  To: persistence_at_glassfish.dev.java.net
  Subject: Re: JoinColumn of relationship with subclasses which has joined strategy?


  Comments inline...


  On 11/16/06, Wonseok Kim <guruwons_at_gmail.com> wrote:
    Hi all,
    There is an interesting but not clear issue which Sahoo brought up.

    For example, there are entities which have Joined inheritance strategy.

    @Entity @Inheritance(strategy=JOINED)
    public class SuperClass {
      @Id @Column(name="ID") String id;
    }

    @Entity @PrimaryKeyJoinColumn(name="PK", referencedColumnName="ID")
    public class SubClass extends SuperClass {...}

    And if other entity references the Subclass like below,

    @Entity
    public class User {
      ...
      @JoinColumn(name="USER_ID", referencedColumnName="???")
      SubClass subClass;
    }

    What should be the referencedColumnName value? Should it be the primary column of SubClass table or SuperClass?
    You can see below Sahoo's message.

    What do you think?

  My original understanding of the spec has been that referencedColumnName always refers to the column of the target entity's table.
  So "PK" (the primary key column of the SubClass) is, I think, right one.

  Spec: 9.1.6 JoinColumn Annotation says
  ...If the referencedColumnName element is missing, the foreign key is assumed to refer to the primary key of the referenced table.
   
  Table 8 in p.170 says
  referencedColumnName: (Optional) The name of the column referenced this foreign key column. When used with mappings, the column is in the table of the target entity.

  There is no mention about inheritance, but my interpretation is that the column of the target table should be used.

  Is there more clear idea?

  Thanks,
  -Wonseok


    On 16 Nov 2006 03:01:10 -0000, ss141213_at_dev.java.net <ss141213_at_dev.java.net> wrote:
      https://glassfish.dev.java.net/issues/show_bug.cgi?id=1153

      ------- Additional comments from ss141213_at_dev.java.net Thu Nov 16 03:01:09 +0000 2006 -------
      Hi Wonseok,

      Although Table B has ID1 and ID2 as primary key columns and those two columns
      are also foreign keys to A.ID1 and A.ID2, but the IDs for the derived entity B
      should still be mapped to A.ID1 and A.ID2. That's my understanding. In the
      example below(thanks to Sherry Shen who brought this use case to my attention)
      where the columns in derived classes have been renamed to PK1 and PK2
      respectively, should the referencedColumnNames in @JoinTable be using PK1 and
      PK2 or ID1 and ID2? I think, they should be using ID1 and ID2 as shown below.

      @Embeddable class Person {
      String id1;
      String id2;
      }

      @Entity
      @Inheritance(strategy=JOINED)
      class Person {
         @EmbeddedId PersonPK personPK;
         ...
      }

      @Entity
      @PrimaryKeyJoinColumns({
             @PrimaryKeyJoinColumn(name="PK1", referencedColumnName="ID1"),
             @PrimaryKeyJoinColumn(name="PK2", referencedColumnName="ID2")
      })
      public class NaturalPerson {
         @ManyToMany(cascade=CascadeType.ALL)
         @JoinTable(name="PARENT_CHILDREN",
                      joinColumns={
                        @JoinColumn(name="P_ID1", referencedColumnName="ID1"),
                        @JoinColumn(name="P_ID2", referencedColumnName="ID2")
                      },
                      inverseJoinColumns={
                        @JoinColumn(name="C_ID1", referencedColumnName="ID1"),
                        @JoinColumn(name="C_ID2", referencedColumnName="ID2")
                      }
                   )
         List<NaturalPerson> children;
      }

      With the current fix in place, this does not work. It works when we use PK1 and
      PK2 as the referenced column names in @JoinTable.

      Thanks,
      Sahoo