Kiran
Kiran

Reputation: 21

Hibernate/JPA: using partial composite primary key from parent as both foreign key and primary key in child

I have 2 entity classes: Student is parent and Address is child with one to one mapping:

Student

student_id int (pk), roll_no int (pk), name varchar

Address

student_id (pk, fk), country varchar

student_id in address entity is both the primary key and foreign key

Student Entity class:

@Entity
@Table(name = "student")
public class Student {

    @EmbeddedId
    private StudentPrimaryKey studentPrimaryKey;

    @Column(name = "name")
    private String name;

    @OneToOne(mappedBy = "student", cascade = CascadeType.ALL)
    private Address address;
    ........

StudentPrimaryKey class:

@Embeddable
public class StudentPrimaryKey implements Serializable{

    @Column(name = "student_id")
    private long id;

    @Column(name = "roll_no")
    private long rollNo;
    ....

Address Entity class:

@Entity
@Table(name = "address")
public class Address {

    @Id
    @Column(name  = "student_id")
    private long id;

    @Column(name  = "country")
    private String country;

    @OneToOne
    @JoinColumn(name = "student_id")
    @MapsId
    private Student student;
    .......

Exception is - org.hibernate.AnnotationException: Implicit column reference in the @MapsId mapping fails, try to use explicit referenceColumnNames

I understand that there are 2 primary key columns in parent table and @MapsId is unable to figure out which one it should map the foreign key to in parent table, so I tried using referencedColumnName in Address Entity -

@OneToOne
    @JoinColumn(name = "student_id", referencedColumnName = "student_id")
    @MapsId
    private Student student; 

New Exception: Unable to find column reference in the @MapsId mapping: roll_no

From above, it is trying to find the missingcolumn from composite primary key in parent class, but we don't need this column.

[Hibernate - Composite Primary Key contains Foreign Key

This is one of the link that shares the same problem which says JPA/ hibernate doesn't allow partial composite primary keys to be the foreign keys.

Please provide your support to help me handle this.

Upvotes: 1

Views: 2469

Answers (1)

Brian Vosburgh
Brian Vosburgh

Reputation: 3276

If a Student can be uniquely identified only by a combination of both its id and rollNo, then the corresponding Address also requires both fields in its primary key/foreign key and should look like this (note it uses the same @EmbeddedId, StudentPrimaryKey):

@Entity
@Table(name = "address")
public class Address {

    @EmbeddedId
    private StudentPrimaryKey primaryKey;

    @MapsId
    @JoinColumns({
        @JoinColumn(name="student_id", referencedColumnName="student_id"),
        @JoinColumn(name="roll_no", referencedColumnName="roll_no") })
    @OneToOne
    Student student;

    @Column(name  = "country")
    private String country;

    ...

You will also need to add the roll_no column to the address table.

If a Student can be uniquely identified by simply its id (as implied by your Address mappings), then you can remove rollNo from the primary key and use a simple @Id mapping on id and @Basic mapping on rollNo.

Upvotes: 1

Related Questions