插入时Hibernate OneToOne双向外键

时间:2016-03-31 15:42:04

标签: oracle hibernate foreign-keys

使用hibernate调用insert时遇到问题。外键不会传递给OneToOne映射中的子项,但它适用于OneToMany映射。

School.java

private long schoolId;
private set<Student> students;
private Principal principal;

@Id
@Column(name = "SCHOOL_ID", unique = true, nullable = false, precision = 15, scale = 0)
public long getSchoolId() {
    return schoolId;
}
public void setSchoolId( long schoolId ) {
    this.schoolId = schoolId;
}

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "school")
public set<Student> getStudents() {
    return students;
}
public void setStudents( set<Student> students ) {
    this.students = students;
}

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "school")
public Principal getPrincipal() {
    return principal;
}
public void setPrincipal( Principal principal ) {
    this.principal = principal;
}

Student.java

private long studentId;
private School school;
other data....

@Id
@Column(name = "STUDENT_ID", unique = true, nullable = false, precision = 15, scale = 0)
public long getStudentId() {
    return studentId;
}
public void setStudentId( long studentId ) {
    this.studentId = studentId;
}

@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SCHOOL_ID", nullable = false)
public School getSchool() {
    return school;
}
public void setSchool( School school ) {
    this.school = school;
}

Principal.java

private long principalId;
private School school;
//other data....

@Id
@Column(name = "PRINCIPAL_ID", unique = true, nullable = false, precision = 15, scale = 0)
public long getPrincipalId() {
    return principalId;
}
public void setPrincipalId( long principalId ) {
    this.principalId = principalId;
}

@JsonIgnore
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SCHOOL_ID", nullable = false)
public School getSchool() {
    return school;
}
public void setSchool( School school ) {
    this.school = school;
}

通过这个例子,当我尝试保存一个School对象时,hibernate将调用学校上的insert,然后是Students,然后是Principal。当它调用所有学生的插入时,休眠调用

insert into STUDENT ( SCHOOL_ID, STUDENT_ID ) values (?, ?)

这是正确的。但是当它试图在主体上调用insert时,hibernate调用

insert into PRINCIPAL ( PRINCIPAL_ID) values (?)

导致

  

ORA-01400:无法插入NULL(“PRINCIPAL”。“SCHOOL_ID”)

因为没有插入School对象的外键。我不明白为什么它为OneToMany表插入外键,而不是OneToOne表。有谁知道如何解决这一问题?这些表是双向的。

另外,我有一个控制器,它接收School对象并保存到DB。该对象看起来像这样

{
    "name" : "data",
    "students" : [ {"name", "data"}],
    "principal" : {"name", "data"}
}

当我收到这个学校对象时,我是否必须循环通过孩子并将父母设置为学校?因为在这个例子中它只有2个级别,但我需要构建4-5级别,并且不想一直循环设置每个父级。我不必使用双向工作,如果是单向工作,我会这样做。

1 个答案:

答案 0 :(得分:0)

将mappedBy添加到Principal类中的OneToOne批注:

 @OneToOne(mappedBy="principal", fetch = FetchType.LAZY)