简体   繁体   English

为什么级联持久化在 Hibernate 中不适用于多对多关系?

[英]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 个类(实体) StudentCourse代码片段

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.没有例外。

  1. You should use @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;

   // ...
}
  1. If you use bidirectional association you should take care about synchronization of both sides of association.如果您使用双向关联,您应该注意关联双方的同步。 So, you should add the following methods to your 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);
  1. As it mentioned in the documentation :正如它在文档中提到的:

For @ManyToMany associations, the REMOVE 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 a ConstraintViolationException .由于另一端可能被父端的其他实体引用,因此自动删除可能以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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM