Spring Data Jpa - ManyToMany - 删除连接表的实体

时间:2018-01-24 09:40:53

标签: java spring hibernate spring-data-jpa

我有这两个类:

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;

}

当我删除ClassB时(通过spring data jpa存储库),Hibernate也会删除ClassA的实例,而我只想删除JOIN_TABLE_NAME表中的行(另一个问题是,由于级联模式,删除ClassA实体也会删除这些ClassB引用的其他ClassA

有没有办法处理这个问题而无需创建连接实体并用引用新连接实体的@ManyToMany替换@OneToMany注释?

1 个答案:

答案 0 :(得分:4)

Cascade在manyToMany中移除它不仅应用于链接表,还应用于关联的另一端。

所以继承删除的Cascade.ALL对于manyToMany来说几乎总是一件坏事,因为它不仅会从关联表中删除内容。

你想要的是在实体中添加和删除方法来完成工作并保持两个列表同步:

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