Hibernate один к одному однонаправленный - идентификаторы не назначены
На моих модульных тестах я получаю 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..
}
EnrolledInfo Entity
@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 ответ
Ваш EnrolledInfo имеет идентификатор студента в качестве своего идентификатора, и стратегия генерации отсутствует, поскольку его идентификаторы происходят из отношения, так как это родительский идентификатор (ученик). Чтобы это работало, студент должен быть известен во время сохранения.
Таким образом, 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;