hibernate composite Primary key contains a composite foreign key, how to map this

Kent picture Kent · Feb 3, 2010 · Viewed 22.4k times · Source

I searched there, and didn't find any similar topic, so I am posting a new question.

I am working with Hibernate on an existing Database. The table structure and data we are not allowed to change. The application is reading data from the database and migrating to another datastore based on some logic.

Now the problem is about a composite PK mapping. e.g.

Table A has a composite PK.

Table A
--------
a1 (pk)
a2 (pk)
a3 (pk)
a4 (pk)
foo
bar
========

Table B has a composite PK too, and one part of this composite PK is A's PK, here is working as FK as well.

Table B
--------
a1 (fk,pk)
a2 (fk,pk)
a3 (fk,pk)
a4 (fk,pk)
b1 (pk)
b2 (pk)
b3 (pk)
foo
bar
========

I tried several ways, and none of them works. Can anyone tell a working Hibernate mapping solution? better in annotation style.

Answer

Vinodh Ramasubramanian picture Vinodh Ramasubramanian · Feb 3, 2010

Set up A's entity object as a @ManyToOne in B's pk Class.

So if you have

Class A
Class APK - A's Primary Key

Class B
Class BPK - B's primary Key.

BPK will contain A as an attribute

@Embeddable
public class BPK implements serializable {
  ....
  private A a;

  @ManyToOne(fetch=FetchType.EAGER)
  @JoinColumns ({
    @JoinColumn(name="...", referencedColumnName = "..."),
    @JoinColumn(name="...", referencedColumnName = "..."),
    ...
  })
  public getA() {
    return this.a;
  }
}

From the documentation

@Embeddable inherit the access type of its owning entity unless the Hibernate specific annotation @AccessType is used. Composite foreign keys (if not using the default sensitive values) are defined on associations using the @JoinColumns element, which is basically an array of @JoinColumn. It is considered a good practice to express referencedColumnNames explicitly. Otherwise, Hibernate will suppose that you use the same order of columns as in the primary key declaration.