Hibernate多对多级联删除

我在我的数据库3个表:StudentsCoursesStudents_Courses

学生可以有多个课程,课程可以有多个学生。Students和之间存在多对多关系Courses

我为我的项目和课程添加了3个案例Courses

  • (a)当我添加用户时,它会保存得很好,
  • (b)当我为学生添加课程时,它会在User_Courses-预期行为中创建新的行。
  • (三)当我试图删除学生,则在删除适当的记录StudentsStudents_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

回到顶部