【发布时间】:2017-11-17 19:28:38
【问题描述】:
我在Student_Teacher-表(无实体)中的学生和老师之间存在多对多关系。
Student: Teacher(owning-side): Student_Teacher
1= Tim 50= Mrs. Foo 1= 1 50
2= Ann 51= Mr. Bar 2= 1 51
3= 2 50
4= 2 51
正如您在上面看到的每个学生当前都与每个老师相关。
现在我喜欢删除 Ann,我喜欢使用数据库的级联技术从 Student_Teacher-table 中删除条目,但我不喜欢删除其他学生、老师或其他关系。
这就是我在学生实体中所拥有的:
@ManyToMany(mappedBy="students")
public Set<Teacher> getTeachers() {
return teachers;
}
这就是我在教师实体中所拥有的:
@ManyToMany
@JoinTable(name="Student_Teacher", joinColumns = {
@JoinColumn(name="StudentID", referencedColumnName = "TeacherID", nullable = false)
}, inverseJoinColumns = {
@JoinColumn(name="TeacherID", referencedColumnName = "StudentID", nullable = false)
})
public Set<Student> getStudents() {
return students;
}
现在我喜欢使用数据库的delete cascade 功能。我重复一遍:数据库的删除级联功能仅针对 Student_Teacher 表!
问题:
org.h2.jdbc.JdbcSQLException: Referentielle Integrität verletzt: "FK_43PMYXR2NU005M2VNEB99VX0X: PUBLIC.Student_Teacher FOREIGN KEY(StudentID) REFERENCES PUBLIC.Student(StudentID) (2)"
Referential integrity constraint violation: "FK_43PMYXR2NU005M2VNEB99VX0X: PUBLIC.Student_Teacher FOREIGN KEY(StudentID) REFERENCES PUBLIC.Student(StudentID) (2)"; SQL statement:
delete from "Student" where name='Ann'
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:425)
我不能用的是
@ManyToMany(cascade={CascadeType.REMOVE})
因为文档告诉我:
(可选)必须级联到关联目标的操作。
“目标”是老师,所以这个级联会删除老师(我不喜欢删除)。
问题:
如何配置实体以仅使用数据库的级联功能删除 Ann 和关系?
概念证明:
我尝试了另一个功能,我注意到可以像这样自然地配置外键:
@ManyToMany(cascade = { CascadeType.REMOVE })
@JoinTable(name="Student_Teacher", joinColumns = {
@JoinColumn(name="StudentID", referencedColumnName = "TeacherID", nullable = false, foreignKey=@ForeignKey(foreignKeyDefinition="FOREIGN KEY (StudentID) REFERENCES Student ON DELETE NO ACTION"))
}, inverseJoinColumns = {
@JoinColumn(name="TeacherID", referencedColumnName = "StudentID", nullable = false, foreignKey=@ForeignKey(foreignKeyDefinition="FOREIGN KEY (TeacherID) REFERENCES Teacher ON DELETE NO ACTION"))
})
public Set<Student> getStudents() {
return students;
}
问题是:这工作正常,但要触发删除Student_Teacher 中的条目,我必须在两侧指定@ManyToMany(cascade = { CascadeType.REMOVE })。 Hibernate 不解析foreignKeyDefinition,只看到CascadeType.REMOVE 并将目标实体(和引用的学生Tim)从缓存中删除,但它们仍在数据库中!!!所以我必须在掉线后立即清除休眠会话,以重新读取教师 Mrs. Foo 和 Mr. Bar 以及学生 Tim 的存在。
【问题讨论】:
-
在学生和老师之间保留多对多关系表的意义何在,就像您说的,“每个学生都与每个老师都有关系”?
-
@Redisson_RuiGu 每个学生都与每个老师相关是当前的情况。安实际上已经毕业了,安依赖的内心担忧不清楚(当然,有人应该问过她,但不是我,嘿,安是我的想象……也许她的生活方式,与巴先生或 Foo 夫人的期望不同 - 谁是也是我的一个想象)。好吧,我需要删除 Ann,因为她不再是大学的学生了。但是,如果 Ann 退学,Tim、Foo 夫人和 Bar 先生都不会被免职。
标签: java hibernate many-to-many reverse-engineering