我在休眠状态下遇到以下无法解释的行为,我希望有人可以提供有关发生情况的解释。
我在@OneToMany
和Instructor
之间具有双向Course
关联。因为他们有一个CascadeType.PERSIST
,所以我希望当我创建一个Course
对象并将其关联到Instructor
时,反之亦然,然后在讲师上调用.save()
方法时,尽管这两个对象都将保留在数据库中导致只保留Instructor
而没有课程。
如果我为例如persist()
调用session.persist(instructor)
方法,则讲师和课程都将保留。
这是我的实体和我的主要方法。
讲师:
@Entity
@Table(name = "instructor")
public class Instructor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "instructor_detail_id")
private InstructorDetail instructorDetail;
@OneToMany(mappedBy = "instructor", cascade = {CascadeType.DETACH,
CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)
private List<Course> courses = new ArrayList<>();
public Instructor() {
}
public Instructor(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public InstructorDetail getInstructorDetail() {
return instructorDetail;
}
public void setInstructorDetail(InstructorDetail instructorDetail) {
this.instructorDetail = instructorDetail;
}
public List<Course> getCourses() {
return courses;
}
public void setCourses(List<Course> courses) {
this.courses = courses;
}
@Override
public String toString() {
return "Instructor{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", instructorDetail=" + instructorDetail +
", courses=" + courses +
'}';
}
public void addCourse(Course course) {
courses.add(course);
course.setInstructor(this);
}
}
课程
@Entity
@Table(name = "course")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "title")
private String title;
@ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)
@JoinColumn(name = "instructor_id")
private Instructor instructor;
public Course(String title) {
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Instructor getInstructor() {
return instructor;
}
public void setInstructor(Instructor instructor) {
this.instructor = instructor;
}
}
主要
public class Test {
public static void main(String[] args) {
//create session factory
SessionFactory sessionFactory = new Configuration()
.configure("com/ysoft/config/hibernate.cfg.xml")
.addAnnotatedClass(Instructor.class)
.addAnnotatedClass(InstructorDetail.class)
.addAnnotatedClass(Course.class)
.buildSessionFactory();
//create session
Session session = sessionFactory.getCurrentSession();
try (sessionFactory) {
session.beginTransaction();
Instructor instructor = new Instructor("John", "Doe", "[email protected]");
InstructorDetail instructorDetail = new InstructorDetail("http://www.something.com", "Coding");
Course mathCourse = new Course("Math");
Course englishCourse = new Course("English");
Course sportsCourse = new Course("Sports");
instructor.addCourse(mathCourse);
instructor.addCourse(englishCourse);
instructor.addCourse(sportsCourse);
instructor.setInstructorDetail(instructorDetail);
session.save(instructor);
session.getTransaction().commit();
System.out.println("Persisted" + instructor);
}
}
}
[如果我将@OneToMany
级联数组更改为CascadeType.ALL
,那么它将起作用-但我不知道为什么,因为相关类型已经存在。
子端不应该指定级联-引用最新的Hibernate文档:
@OneToMany
关联根据定义是父关联,甚至如果是单向的或双向的。只有父母一方关联的意义在于级联其实体状态转换是有意义的给孩子们。