如何正确设置与JPA Hibernate的@OneToOne关系?

时间:2017-03-15 19:50:15

标签: java mysql spring hibernate jpa

我对此非常陌生,我试图在Student对象和Grades对象之间建立一个简单的一对一关系。我在hsqldb内存数据库中使用spring boot。我先显示我的代码,然后解释我的问题。

Student.java

@Entity
public class Student {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  private String firstName;
  private String lastName;

  @OneToOne(cascade = CascadeType.ALL)
  private Grades grades;

  //Getters and setters
}

Grades.java

@Entity
  public class Grades {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  private int midterm;
  private int finalExam;

  @OneToOne(cascade = CascadeType.ALL)
  private Student student;

  //Getters and setters
}

StudentRepository.java

public interface StudentRepository extends JpaRepository<Student, Long> {
}
  1. 我的学生和成绩设置是否正确?我只是一个简单的一对一关系,我将Grades ID作为外键存储在Student对象中。

  2. 每当我使用new Grades()创建一个Grades对象并将其传递给构造函数中的Student对象时,它允许我为多个学生分配相同的Grades对象。当他们用一对一注释时,这怎么可能?

  3. 我打开了hibernate sql日志,看看使用数据库时发生了什么。它似乎将students_id存储在Student对象中,但它将Grades对象中的student_id显示为null。为什么这是空的?

  4. 感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

  

我的学生和成绩设置是否正确?

这是值得怀疑的。关系的双方都被映射为关系的所有者。其中一个应该映射为所有者,其他应该使用mappedBy注释的@OneToOne属性。 @OneToOne

  

每当我使用新的Grades()创建一个Grades对象并传递它   在构造函数中的Student对象中,它允许我分配   同一个等级对象对多个学生。这怎么可能呢?   他们用一对一注释?

您应创建复合主键或使用唯一性约束禁止多个Grades使用相同的Student记录。

  

我打开了hibernate sql日志,看看使用时发生了什么   数据库。它似乎只是将students_id存储在Student对象中   很好,但它将Grades对象中的student_id显示为null。为什么   这是空的吗?

看起来Hibernate使用外键列生成了两个表。只应生成一个。

您必须指定一方作为关系的所有者。另一方应该使用mappedBy注释的@OneToOne属性告诉Hibernate关系映射的位置。

...
@OneToOne(mappedBy="grades")
private Student student;
...