Reputation: 21
I have 2 entity classes: Student is parent and Address is child with one to one mapping:
student_id int (pk), roll_no int (pk), name varchar
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
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