Spring Data JPA - ManyToMany - 删除关联表中的实体

13

我有这两个类:

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;

}
当我通过Spring Data JPA存储库删除ClassB时,Hibernate也会删除ClassA的实例,但我只想删除JOIN_TABLE_NAME表中的行(另一个问题是,由于级联模式,删除ClassA实体还会删除被这些ClassA引用的其他ClassB)。
是否有方法可以处理此问题,而无需创建联接实体并将@ManyToMany注释替换为引用新联接实体的@OneToMany注释?
1个回答

14

在ManyToMany关系中,级联删除不仅适用于链接表,而且也适用于关联的另一侧。

因此,Cascade.ALL继承了remove,对于ManyToMany关系来说几乎总是不好的选择,因为它最终会从关联表中删除东西。

你需要的是在实体中拥有add和remove方法来完成这项工作,并保持两个列表同步:

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);
    }  
}

3
谢谢Zeromus。这实际上是我缺失的拼图。我已经将删除操作绑定到一个被注释为 @PreRemove 的方法(在 ClassB 中),以自动处理该操作。 - Thoomas
1
@Thoomas 你是怎么用 @PreRemove 注解实现这个 remove 函数的?我尝试时却得到了一个编译错误:Callback methods annotated on the bean class must return void and take no arguments: javax.persistence.PreRemove - Mahan_F
1
@Mahan_F ClassB有一个带有以下签名的方法:@PreRemove public void preRemove() { ... } - Thoomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接