Hibernate多对多级联删除
我在我的数据库3个表:Students,Courses和Students_Courses
学生可以有多个课程,课程可以有多个学生。Students和之间存在多对多关系Courses。
我为我的项目和课程添加了3个案例Courses。
- (a)当我添加用户时,它会保存得很好,
- (b)当我为学生添加课程时,它会在User_Courses-预期行为中创建新的行。
- (三)当我试图删除学生,则在删除适当的记录Students和Students_Courses,但它也删除Courses其中不需要的记录。即使课程中没有任何用户,我也希望课程在那里。
下面是我的表和注释类的代码。
    CREATE TABLE `Students` (    `StudentID` INT(11) NOT NULL AUTO_INCREMENT,
    `StudentName` VARCHAR(50) NOT NULL 
    PRIMARY KEY (`StudentID`)
)
CREATE TABLE `Courses` (
    `CourseID` INT(11) NOT NULL AUTO_INCREMENT,
    `CourseName` VARCHAR(50) NOT NULL 
    PRIMARY KEY (`CourseID`)
)
CREATE TABLE `Student_Courses` (
    `StudentId` INT(10) NOT NULL DEFAULT '0',
    `CourseID` INT(10) NOT NULL DEFAULT '0',
    PRIMARY KEY (`StudentId`, `CourseID`),
    INDEX `FK__courses` (`CourseID`),
    INDEX `StudentId` (`StudentId`),
    CONSTRAINT `FK__courses` FOREIGN KEY (`CourseID`) REFERENCES `courses` (`CourseID`) ON DELETE NO ACTION,
    CONSTRAINT `FK_students` FOREIGN KEY (`StudentId`) REFERENCES `students` (`StudentId`)
)
这是Hibernate生成的Java代码:
@Entity@Table(name = "Students")
public class Students implements java.io.Serializable {
    private Integer StudentID;
     private String Students;
    private Set<Courses> Courseses = new HashSet<Courses>(0);
    public Students() {
    }
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "StudentID", unique = true, nullable = false)
    public Integer getStudentID() {
        return this.StudentID;
    }
    public void setStudentID(Integer StudentID) {
        this.StudentID = StudentID;
    }
    @Column(name = "Students", nullable = false, length = 50)
    public String getCampaign() {
        return this.Students;
    }
    public void setCampaign(String Students) {
        this.Students = Students;
    }
 @ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    @JoinTable(name = "Student_Courses", joinColumns = {
        @JoinColumn(name = "StudentId", nullable = false, updatable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "CourseID", nullable = false, updatable = false)})
    public Set<Courses> getCourseses() {
        return this.Courseses;
    }
     public void setCourseses(Set<Courses> Courseses) {
        this.Courseses = Courseses;
    }
    }
    @Entity
@Table(name = "Courses")
public class Courses implements java.io.Serializable {
  private Integer CourseID;
    private String CourseName;
     private Set<Students> Studentses = new HashSet<Students>(0);
    public Courses() {
    }
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "CourseID", unique = true, nullable = false)
    public Integer getCourseID() {
        return this.CourseID;
    }
    public void setCourseID(Integer CourseID) {
        this.CourseID = CourseID;
    }
     @Column(name = "CourseName", nullable = false, length = 100)
    public String getCourseName() {
        return this.CourseName;
    }
    public void setCourseName(String CourseName) {
        this.CourseName = CourseName;
    }
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "Courseses")
    public Set<Students> getStudentses() {
        return this.Studentses;
    }
    public void setStudentses(Set<Students> Studentses) {
        this.Studentses = Studentses;
    }
    }
我怎样才能实现我所描述的?我在网络上找不到任何合理的文档。
回答:
我在类似的情况下找到了正确的映射(并在广泛的情况下使用JUnit进行了测试)。我认为我不会发布测试代码,因为适应该示例会花费很长时间。无论如何,关键是:
- mappedBy注释不使用属性,使用连接列
- 列出可能的CascadeTypes排除REMOVE
以OP为例
@ManyToMany(fetch = FetchType.LAZY,        cascade =
        {
                CascadeType.DETACH,
                CascadeType.MERGE,
                CascadeType.REFRESH,
                CascadeType.PERSIST
        },
        targetEntity = Course.class)
@JoinTable(name = "XTB_STUDENTS_COURSES",
        inverseJoinColumns = @JoinColumn(name = "COURSE_ID",
                nullable = false,
                updatable = false),
        joinColumns = @JoinColumn(name = "STUDENT_ID",
                nullable = false,
                updatable = false),
        foreignKey = @ForeignKey(ConstraintMode.CONSTRAINT),
        inverseForeignKey = @ForeignKey(ConstraintMode.CONSTRAINT))
private final Set<Course> courses = new HashSet<>();
@ManyToMany(fetch = FetchType.LAZY,
        cascade =
        {
                CascadeType.DETACH,
                CascadeType.MERGE,
                CascadeType.REFRESH,
                CascadeType.PERSIST
        },
        targetEntity = Student.class)
@JoinTable(name = "XTB_STUDENTS_COURSES",
        joinColumns = @JoinColumn(name = "COURSE_ID",
                nullable = false,
                updatable = false),
        inverseJoinColumns = @JoinColumn(name = "STUDENT_ID",
                nullable = false,
                updatable = false),
        foreignKey = @ForeignKey(ConstraintMode.CONSTRAINT),
        inverseForeignKey = @ForeignKey(ConstraintMode.CONSTRAINT))
private final Set<Student> students = new HashSet<>();
广泛的JUnit测试证明:
- 我可以为学生添加课程,反之亦然
- 如果我从学生中删除课程,则该课程不会被删除
- 反之亦然
- 如果我删除一个学生,则所有课程均被分离,但仍保留在数据库中(对其他学生而言)
- 反之亦然
以上是 Hibernate多对多级联删除 的全部内容, 来源链接: utcz.com/qa/419388.html








