【问题标题】:Spring Data Jpa - ManyToMany - delete entities of the join tableSpring Data Jpa - ManyToMany - 删除连接表的实体
【发布时间】:2018-07-03 07:15:14
【问题描述】:

我有这两个类:

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实体也会删除这些ClassA引用的其他ClassB

有没有什么方法可以处理这个问题,而不必创建连接实体并将@ManyToMany 注释替换为引用新连接实体的@OneToMany

【问题讨论】:

    标签: java spring hibernate spring-data-jpa


    【解决方案1】:

    在 manyToMany 中的 Cascade Remove 不仅适用于链接表,还适用于关联的另一端。

    因此,继承 remove 的 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);
        }  
    }
    

    【讨论】:

    • 谢谢 Zeromus。这实际上是我缺少的一块拼图。我已将删除操作绑定到使用 @PreRemove(在 ClassB 中)注释的方法上,以自动处理该操作。
    • @Thomas 您是如何使用@PreRemove 注释实现这个删除功能的?当我尝试它时,我得到一个编译错误Callback methods annotated on the bean class must return void and take no arguments: javax.persistence.PreRemove
    • @Mahan_F ClassB 有一个带有这个签名的方法:@PreRemove public void preRemove() { ... }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 2021-03-17
    • 1970-01-01
    • 2016-11-12
    相关资源
    最近更新 更多