如何解决为什么在Hibernate中,级联持续存在不适用于多对多关系?
请查看以下来自2个类(实体)Student
和Course
的代码段
public class Student {
...
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "course_student",joinColumns = @JoinColumn(name="student_id"),inverseJoinColumns = @JoinColumn(name="course_id")
)
private List<Course> courses;
...
}
public class Course {
...
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "course_student",joinColumns = @JoinColumn(name="course_id"),inverseJoinColumns = @JoinColumn(name="student_id")
)
private List<Student> students;
...
}
,驱动程序代码如下
try {
session.beginTransaction();
Course course = new Course("Ukulele master class");
Student student1 = new Student("Jishnu","M V","jishnumv@gmail.com");
Student student2 = new Student("Praveen","praveenmv@gmail.com");
course.add(student1);
course.add(student2);
session.save(course);
session.getTransaction().commit();
}
运行此代码时,出现以下异常
Exception in thread "main" java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.jithin.entity.Student
所以我很怀疑。即使我们在课程类中提到了CascadeType.ALL,坚持课程也不会保留关联的学生。那么,为什么在多对多情况下级联不起作用?
nb:当我使用session.save()
保存两个学生对象时,在保存课程对象之前。也不例外。
解决方法
- 您只能在
@JoinTable
关联的拥有方使用@ManyToMany
注释。
@Entity
public class Student {
@ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(name = "course_student",joinColumns = @JoinColumn(name="student_id"),inverseJoinColumns = @JoinColumn(name="course_id"))
private List<Course> courses;
// ...
}
@Entity
public class Course {
@ManyToMany(mappedBy = "courses",cascade = {CascadeType.PERSIST,CascadeType.MERGE})
private List<Student> students;
// ...
}
- 如果使用双向关联,则应注意关联双方的同步。因此,您应该将以下方法添加到
Course
实体中:
public class Course {
public void addStudent(Student student) {
students.add(student);
student.getCourses().add( this );
}
public void removeStudent(Student student) {
students.remove(student);
student.getCourses().remove( this );
}
// ...
}
然后您将可以执行以下操作:
Course course = new Course("Ukulele master class");
Student student1 = new Student("Jishnu","M V","jishnumv@gmail.com");
Student student2 = new Student("Praveen","praveenmv@gmail.com");
course.addStudent(student1);
course.addStudent(student2);
session.save(course);
- 如documentation中所述:
对于
@ManyToMany
关联,REMOVE
实体状态转换没有必要进行级联,因为它会传播到链接表之外。由于另一端可能会被父端的其他实体引用,因此自动删除可能会以ConstraintViolationException
结尾。
这就是为什么您应该避免在cascade = CascadeType.ALL
中使用@ManyToMany
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。