簡體   English   中英

為什么級聯持久化在 Hibernate 中不適用於多對多關系?

[英]Why the Cascading persist does not work with many-to-many relationship in Hibernate?

請查看以下 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;
   
   ...
}

驅動代碼如下

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();
} 

當我運行此代碼時,出現以下異常

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

所以我的懷疑是。 即使我們在 Course 類中提到了 CascadeType.ALL,持久化課程也不會持久化關聯的學生。 那么為什么級聯在多對多的情況下不起作用呢?

注意:當我使用session.save()保存兩個學生對象時,在保存課程對象之前。 沒有例外。

  1. 您應該只在@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. 如果您使用雙向關聯,您應該注意關聯雙方的同步。 因此,您應該將以下方法添加到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","M V","praveenmv@gmail.com");
course.addStudent(student1);
course.addStudent(student2);
session.save(course);
  1. 正如它在文檔中提到的:

對於@ManyToMany關聯, REMOVE實體狀態轉換對於級聯沒有意義,因為它會傳播到鏈接表之外。 由於另一端可能被父端的其他實體引用,因此自動刪除可能以ConstraintViolationException結束。

這就是為什么你應該避免在@ManyToMany使用cascade = CascadeType.ALL

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM