I have a ManyToMany-relation between student and teacher in a Student_Teacher
-table (Entityless).
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
As you see above every Student is currently related to every Teacher.
Now I like to remove Ann and I like to use the database's cascading techique to remove entries from the Student_Teacher
-table but I do neither like to remove other Students, nor Teacher, nor other relationship.
This is what I have in the Student-Entity:
@ManyToMany(mappedBy="students")
public Set<Teacher> getTeachers() {
return teachers;
}
This is what I have in the Teacher-Entity:
@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;
}
Now I like to use the database's delete cascade
functionality. I repeat: The database's delete cascade functionality targeting the Student_Teacher-table only!
The problem:
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)
What i can not use is the
@ManyToMany(cascade={CascadeType.REMOVE})
Because of the documetation tells me:
(Optional) The operations that must be cascaded to the target of the association.
The "target" is the Teacher, so this cascade would remove the Teacher (what I do not like to remove).
Question:
How to configure the entitys to remove Ann and the relation only using the database's cascade functionality?
Proof of Concept:
I tried another feature, I have noticed the possibility to configure the foreign-key nativly like this:
@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;
}
The problem is: This works fine but to trigger the removal of the entries in Student_Teacher
I have to specify @ManyToMany(cascade = { CascadeType.REMOVE })
on both sides. Hibernate do not parse the foreignKeyDefinition
and only see the CascadeType.REMOVE
and drops the target-entitys (and the referenced Student Tim
) out of the cache, but they are still in the database!!! So I have to clear the hibernate-session immendentelly after drop to re-read the existence of the Teachers Mrs. Foo and Mr. Bar and the Student Tim.