title: many to one relationship between composite keys
body: <p>I am building a spring mvc application with hibernate, and JPA that needs to model a few underlying MYSQL data tables that each have composite keys with the same two data types, so each table has its own composite key class, even though all the composite keys are based on the same two data types with exact same property names.  I am getting a hibernate mapping error when I try to compile the app, and I am wondering if this might be because hibernate might not be able to equate the different primary key classes.  <strong>Can someone show me how to fix this so that my app will compile?</strong>  </p>
  
  <p>Here is the part of my <code>Description</code> class that establishes the <code>ManyToOne</code> relationship between <code>Description</code> and <code>Concept</code> classes based on their corresponding composite primary key classes:  </p>
  
  <pre><code>@ManyToOne
  @JoinColumn(name="descriptionPK", referencedColumnName = "conceptPK")
  private Concept concept;
  </code></pre>
  
  <p>Here is the error that I am getting:  </p>
  
  <pre><code>Caused by: org.hibernate.MappingException:  
  Unable to find column with logical name:  
  conceptPK in org.hibernate.mapping.Table(sct2_concept) and its related supertables and secondary tables
  </code></pre>
  
  <p>The code for <code>ConceptPK</code> is:  </p>
  
  <pre><code>@Embeddable
  class ConceptPK implements Serializable {
  
  @Column(name="id", nullable=false)
  protected BigInteger id;
  
  @Column(name="effectiveTime", nullable=false)
  @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
  private DateTime effectiveTime;
  
  public ConceptPK() {}
  public ConceptPK(BigInteger bint, DateTime dt) {
      this.id = bint;
      this.effectiveTime = dt;
  }
  
  /** getters and setters **/
  public DateTime getEffectiveTime(){return effectiveTime;}
  public void setEffectiveTime(DateTime ad){effectiveTime=ad;}
  
  public void setId(BigInteger id) {this.id = id;}
  public BigInteger getId() {return id;}
  
  @Override
  public boolean equals(Object obj) { 
      if (this == obj) return true;
      if (obj == null) return false;
      if (getClass() != obj.getClass()) return false;
      final ConceptPK other = (ConceptPK) obj;
      if (effectiveTime == null) {
          if (other.effectiveTime != null) return false;
      } else if (!effectiveTime.equals(other.effectiveTime)) return false;
      if (id == null) {
          if (other.id != null) return false;
      } else if (!id.equals(other.id)) return false;
      return true;
  }
  
  @Override
  public int hashCode() { 
      int hash = 3;
      hash = 53 * hash + ((effectiveTime == null) ? 0 : effectiveTime.hashCode());
      hash = 53 * hash + ((id == null) ? 0 : id.hashCode());
      return hash;
  }
  }
  </code></pre>
  
  <p>The code for <code>DescriptionPK</code> is:  </p>
  
  <pre><code>@Embeddable
  class DescriptionPK implements Serializable {
  @Column(name="id", nullable=false)
  protected BigInteger id;
  
  @Column(name="effectiveTime", nullable=false)
  @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
  private DateTime effectiveTime;
  
  public DescriptionPK() {}
  public DescriptionPK(BigInteger bint, DateTime dt) {
      this.id = bint;
      this.effectiveTime = dt;
  }
  
  /** getters and setters **/
  public DateTime getEffectiveTime(){return effectiveTime;}
  public void setEffectiveTime(DateTime ad){effectiveTime=ad;}
  
  public void setId(BigInteger id) {this.id = id;}
  public BigInteger getId() {return id;}
  
  @Override
  public boolean equals(Object obj) { 
      if (this == obj) return true;
      if (obj == null) return false;
      if (getClass() != obj.getClass()) return false;
      final DescriptionPK other = (DescriptionPK) obj;
      if (effectiveTime == null) {
          if (other.effectiveTime != null) return false;
      } else if (!effectiveTime.equals(other.effectiveTime)) return false;
      if (id == null) {
          if (other.id != null) return false;
      } else if (!id.equals(other.id)) return false;
      return true;
  }
  
  @Override
  public int hashCode() { 
      int hash = 3;
      hash = 53 * hash + ((effectiveTime == null) ? 0 : effectiveTime.hashCode());
      hash = 53 * hash + ((id == null) ? 0 : id.hashCode());
      return hash;
  }
  }
  </code></pre>