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 of ClassA
, whereas I just want the rows in the JOIN_TABLE_NAME
table to be deleted (the other issue is that, due to the cascade mode, deleting the ClassA
entities also delete other ClassB
referenced by these ClassA
).
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 ?
In JPA, to delete an entity, the entity itself must be managed, meaning that it is present in the persistence context. This means that the calling application should have already loaded or accessed the entity and is now issuing a command to remove it.
First of all you need to create a jpa query method that brings all records belong to id. After that you can do deleteAll() operation on List.
We can use the JPA method deleteById() for deleting the record of the particular primary key.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With