Hibernate many-to-many cascading delete

后端 未结 3 952
半阙折子戏
半阙折子戏 2020-12-08 01:02

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

Students can have multiple courses and courses can have

3条回答
  •  南方客
    南方客 (楼主)
    2020-12-08 01:46

    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:

    • Not use mappedBy attribute for the annotations, use join columns
    • List the possible CascadeTypes excluding REMOVE

    In OP's example

    @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 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 students = new HashSet<>();
    

    Extensive JUnit testing verified that:

    • I can add courses to students and vice versa flawlessly
    • If I remove a course from a student, the course is not deleted
    • Vice versa
    • If I remove a student, all courses are detached but they are still persisted (to other students) in database
    • Vice versa

提交回复
热议问题