persistence@glassfish.java.net

RE: Code related to bug - 796 : Self Many-Many Relationship

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Wed, 26 Jul 2006 11:03:23 -0400

Hello Pramod,
    I took a quick look at this code and it seems that the line in question is attempting to get the attribute name in the case of a defaulted Bi-Directional ManyTo Many. The problem is in this case the reference class attribute is the attribute we are building the mapping for and the FK ends up having the same name as the TFK. I think to solve this issue we will need some concept of ownership, or uni-direction to generate a different default FK name.
--Gordon
  -----Original Message-----
  From: Pramod.Gopinath_at_Sun.COM [mailto:Pramod.Gopinath_at_Sun.COM]On Behalf Of Pramod Gopinath
  Sent: Monday, July 24, 2006 6:08 PM
  To: Guy Pelletier
  Cc: persistence_at_glassfish.dev.java.net
  Subject: Code related to bug - 796 : Self Many-Many Relationship


  Hi Guy
    I have some questions that I wanted to clarify with you. I am working on resolving the glassfish issue :
  https://glassfish.dev.java.net/issues/show_bug.cgi?id=796
  that deals with a "Self-referencing manytomany relationship".

  Problem Description :
  I have a very simple entity Customer that has a unidirectional many-to-many self relationship defined. Sample code that I am using is attached to this email. In short the relationship is defined as :
  @Entity
  @Table(name="CUSTOMER")
  public class Customer {
  ...
      @Id
      @Column(name="CUST_ID")
      public Integer getCustomerId() {
          return customerId;
      }

      public void setCustomerId(Integer id) {
          this.customerId = id;
      }
  ...
      @ManyToMany
      public Collection<Customer> getReportees() {
          return reportees;
      }

      public void setReportees(Collection<Customer> reportees) {
          this.reportees = reportees;
      }

  } // end of Customer entity

  As part of java2db the join table that gets generated is of the form :
  CREATE TABLE CUSTOMER_CUSTOMER (
  reportees_CUST_ID NUMBER(10) NOT NULL,
  PRIMARY KEY (reportees_CUST_ID))

  ALTER TABLE CUSTOMER_CUSTOMER
  ADD CONSTRAINT CSTOMERCUSTOMERreporteesCUSTID
  FOREIGN KEY (reportees_CUST_ID)
  REFERENCES CUSTOMER (CUST_ID)

  This is wrong.

  Questions about Code Understanding :
  When trying to debug the problem, found that in case of a self referencing manytomany relationship the source fields are not getting setup properly as part of the annotation processing. I wanted to find out from you why is there this check in the code :
  glassfish/entity-persistence/src/java/oracle/toplink/essentials/internal/ejb/cmp3/metadata/accessors/CollectionAccessor.processJoinTable( ..)
  starting at line 225 :
  if (getReferenceDescriptor().hasManyToManyAccessorFor(getJavaClassName())) {
     defaultSourceFieldName = getReferenceDescriptor().getManyToManyAccessor(getJavaClassName()).getAttributeName();
  } else {
     defaultSourceFieldName = Helper.getShortClassName(getJavaClass().getName());
  }

  This check is the reason why I do not get the Customer.id field not added to the many-to-many relationship and hence the bug.
  Can you throw more light on this if statement.

  Thanks
  Pramod