Hibernate的多对多级联删除 [英] Hibernate many-to-many cascading delete

查看:189
本文介绍了Hibernate的多对多级联删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的数据库3个表:学生课程 Students_Courses

I have 3 tables in my database: Students, Courses and Students_Courses

学生可以有多种课程和课程可以有多个学生。有学生课程

Students can have multiple courses and courses can have multiple students. There is a many-to-many relationship between Students and Courses.

我有三种情况:我的项目和课程加入到我的课程表。

I have 3 cases for my project and courses added to my Courses table.


  • (一)当我添加一个用户,它被保存的很好,

  • (b)当我添加课程为学生,它 User_Courses 创建新行 - 再次,预期的行为

  • (三)当我试图删除的学生,它是在学生删除相应的记录 Students_Courses ,但它也删除课程这是不需要的记录。即使我没有在课程的任何用户,我希望当然在那里。

  • (a) When I add a user, it gets saved fine,
  • (b) When I add courses for the student, it creates new rows in User_Courses - again, expected behaviour.
  • (c) When I am trying to delete the student, it is deleting the appropriate records in Students and Students_Courses, but it is also deleting Courses records which is not required. Even if I don't have any user in a course, I want the course to be there.

下面是我的code表和注释类。

Below is my code for tables and annotate classes.

    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 code:

This is the Java code generated by Hibernate:

@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;
    }

    }

如何才能实现我所描述?我无法在网上找到任何合理的文档。

How can I achieve what I have described? I could not find any reasonable documentation on the web.

推荐答案

我找到了正确的映射(和测试,与具有广泛的情况下JUnit的)在类似的情况。我不认为我会发布测试code,因为它会采取长的时间来适应这个例子。无论如何,关键是:

I found the correct mapping (and tested that with JUnit with an extensive case) in a similar scenario. I don't think I am going to post testing code because it would take long time to adapt to this example. Anyway the key is to:


  • 不要使用的mappedBy 的注释属性,使用连接列

  • 列出可能的 CascadeTypes 不包括删除

  • Not use mappedBy attribute for the annotations, use join columns
  • List the possible CascadeTypes excluding 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测试证实:

Extensive JUnit testing verified that:


  • 我可以添加课程,学生和反之亦然完美

  • 如果我从学生取出过程中,当然不会被删除

  • 反之亦然

  • 如果我删除一个学生,所有的课程都在数据库中分离,但他们仍然坚持(其他学生)

  • 反之亦然

这篇关于Hibernate的多对多级联删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆