我有2个实体类:学生是父母,地址是孩子,具有一对一映射:
student_id int(pk), roll_no int(pk), 名称varchar
student_id(pk,fk), 国家varchar
地址实体中的student_id既是主键又是外键
学生实体类:
@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类:
@Embeddable
public class StudentPrimaryKey implements Serializable{
@Column(name = "student_id")
private long id;
@Column(name = "roll_no")
private long rollNo;
....
地址实体类:
@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;
.......
例外是- org.hibernate.AnnotationException:@MapsId映射中的隐式列引用失败,请尝试使用显式referenceColumnNames
我知道父表中有2个主键列,而@MapsId无法确定应将外键映射到父表中的哪一个,因此我尝试在地址实体中使用referencedColumnName-
@OneToOne
@JoinColumn(name = "student_id", referencedColumnName = "student_id")
@MapsId
private Student student;
新异常: 在@MapsId映射中找不到列引用:roll_no
从上面开始,它试图从父类的复合主键中查找缺少的列,但是我们不需要此列。
[Hibernate - Composite Primary Key contains Foreign Key
这是存在相同问题的链接之一,该问题表明JPA /休眠状态不允许部分组合主键作为外键。
请提供您的支持以帮助我解决此问题。
答案 0 :(得分:1)
如果只能通过Student
和id
的组合唯一地标识rollNo
,则相应的Address
也需要在其主键/外键,并且应如下所示(请注意,它使用相同的@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;
...
您还需要将roll_no
列添加到address
表中。
如果Student
可以仅通过其id
来唯一标识(如您的Address
映射所暗示),则可以从主键中删除rollNo
并使用@Id
上的简单id
映射和@Basic
上的rollNo
映射。