Hibernate一对一单向 - 未分配ID

时间:2015-03-31 13:55:56

标签: java spring hibernate one-to-one

在我的单元测试中,我得到了JpaSystemException: ids for this class must be manually assigned before calling save() error。我重写了我的实体,使问题更短,更易读。

因此学生与表EnrolledInfo具有可选的一对一关系。

学生实体

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

    @Id
    @Column(name = "studentId")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long studentId;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "student", cascade = CascadeType.ALL)
    private EnrolledInfo enrolledInfo;

    private String firstName;

    private String lastName;

    // setters&getters etc..    
}

注册信息实体

@Entity
@Table(name = "EnrolledInfo")
public class EnrolledInfo implements Serializable {

    @Id
    private Long studentId;

    @OneToOne(fetch = FetchType.Eager)
    @PrimaryKeyJoinColumn
    @JsonBackReference
    private Student student;

    @Column(name = "enrolledDate")
    private Date enrolledDate;

    @Column(name = "paidTuition")
    private Boolean paidTuition;

    // setters&getters etc..
}

将它们放在一起进行测试(此错误)

在保存学生之前,我当然不必保存enrolledInfo实体吗?

@Test
public void student_test() {

  Student student = new Student();
  EnrolledInfo enrolledInfo = new EnrolledInfo(); 
  enrolledInfo.setPaidTuition(true);

  student.setEnrolledInfo(enrolledInfo);        
  studentDao.save(student);
  // errors on // JpaSystemException: ids for this class must be manually assigned before calling save():
}

1 个答案:

答案 0 :(得分:1)

您的EnrolledInfo将studentId作为其ID,并且没有生成策略导致其ID来自关系,因为它是其父ID(学生)。为了工作,学生必须在保存期间知道。

因此,EnrolledInfo必须知道它的学生,jpa不会处理关系本身的两面,因此可以手动设置它们。

  Student student = new Student();
  EnrolledInfo enrolledInfo = new EnrolledInfo(); 
  enrolledInfo.setPaidTuition(true);
  enrolledInfo.setStudent(student);

  student.setEnrolledInfo(enrolledInfo);        
  studentDao.save(student);

现在在JPA2中,正确的注释将是:

@Entity
@Table(name = "EnrolledInfo")
public class EnrolledInfo implements Serializable {

    @Id
    private Long studentId;

    @OneToOne(fetch = FetchType.Eager)
    @Id
    @JsonBackReference
    private Student student;

在JPA1中使用@PrimaryKeyJoinColumn你需要提供完整的映射(你现在应该使用JPA2,所以没有理由使用旧版本,但以防万一):

@Entity
@Table(name = "EnrolledInfo")
public class EnrolledInfo implements Serializable {

    @Id
    @Column(name="STUDENT_ID")
    private Long studentId;

    @OneToOne(fetch = FetchType.Eager)
    @PrimaryKeyJoinColumn(name="STUDENT_ID", referencedColumnName="STUDENT_ID")
    @JsonBackReference
    private Student student;