Spring Data Jpa - ManyToMany - delete entities of the join table
Cascade Remove in a manyToMany it's not only applied to the link table, but to the other side of the association as well.
So Cascade.ALL which inherit remove too is almost always a bad thing to have on a manyToMany as it ends up deleting things not only from association table.
What you want is to have add and remove method in your entities to do the work and keep both list synchronized:
public class ClassA extends [...] implements [...] {
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinTable(name = JOIN_TABLE_NAME,
joinColumns = @JoinColumn(name = COLUMN_REF_A, referencedColumnName = COLUMN_ID_A),
inverseJoinColumns = @JoinColumn(name = COLUMN_REF_B, referencedColumnName = COLUMN_ID_B))
private List<ClassB> fieldClassB;
public void addClassB(ClassB b) {
fieldClassB.add(b);
b.fieldClassA().add(this);
}
public void removeClassB(ClassB b) {
fieldClassB.remove(b);
b.fieldClassA().remove(this);
}
}
Related videos on Youtube
Thoomas
"Quality means doing it right even when no one is looking." - Henry Ford
Updated on September 15, 2022Comments
-
Thoomas over 1 year
I have these two classes :
public class ClassA extends [...] implements [...] { @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinTable(name = JOIN_TABLE_NAME, joinColumns = @JoinColumn(name = COLUMN_REF_A, referencedColumnName = COLUMN_ID_A), inverseJoinColumns = @JoinColumn(name = COLUMN_REF_B, referencedColumnName = COLUMN_ID_B)) private List<ClassB> fieldClassB; } public class ClassB extends [...] implements [...] { @ManyToMany(fetch = FetchType.LAZY, mappedBy = "fieldClassB", cascade = CascadeType.ALL) private List<ClassA> fieldClassA; }
When I delete
ClassB
(via the spring data jpa repository), Hibernate also deletes instances ofClassA
, whereas I just want the rows in theJOIN_TABLE_NAME
table to be deleted (the other issue is that, due to the cascade mode, deleting theClassA
entities also delete otherClassB
referenced by theseClassA
).Is there any way to handle this without having to create the join entity and to replace the
@ManyToMany
annotations by@OneToMany
referencing the new join entity ?