[英]Why the Cascading persist does not work with many-to-many relationship in Hibernate?
Please look at the following code snippets from 2 classes (Entities) Student
and Course
请查看以下 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;
...
}
and the driver code is as follows驱动代码如下
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","M V","praveenmv@gmail.com");
course.add(student1);
course.add(student2);
session.save(course);
session.getTransaction().commit();
}
When I run this code I am getting the following exception当我运行此代码时,出现以下异常
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
So my doubt is.所以我的怀疑是。 persisting the Course does not persist the associated Student(s) even though we have mentioned CascadeType.ALL in the Course class.即使我们在 Course 类中提到了 CascadeType.ALL,持久化课程也不会持久化关联的学生。 So why the cascading is not working in the case of many to many?那么为什么级联在多对多的情况下不起作用呢?
nb: When I saved both the student objects using session.save()
, before saving the course object.注意:当我使用session.save()
保存两个学生对象时,在保存课程对象之前。 There were no exception.没有例外。
@JoinTable
annotation only on the owning side of the @ManyToMany
association.您应该只在@ManyToMany
关联的拥有方使用@JoinTable
注释。@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
entity:因此,您应该将以下方法添加到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 );
}
// ...
}
and then you will be able to do something like this:然后你将能够做这样的事情:
Course course = new Course("Ukulele master class");
Student student1 = new Student("Jishnu","M V","jishnumv@gmail.com");
Student student2 = new Student("Praveen","M V","praveenmv@gmail.com");
course.addStudent(student1);
course.addStudent(student2);
session.save(course);
For
@ManyToMany
associations, theREMOVE
entity state transition doesn't make sense to be cascaded because it will propagate beyond the link table.对于@ManyToMany
关联,REMOVE
实体状态转换对于级联没有意义,因为它会传播到链接表之外。 Since the other side might be referenced by other entities on the parent-side, the automatic removal might end up in aConstraintViolationException
.由于另一端可能被父端的其他实体引用,因此自动删除可能以ConstraintViolationException
结束。
That is why you should avoid to use cascade = CascadeType.ALL
in the @ManyToMany
.这就是为什么你应该避免在@ManyToMany
使用cascade = CascadeType.ALL
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.