JPA + 休眠 + 春季 + 一对多删除级联

2022-09-01 08:41:01

我已经阅读了一些相关的问题,但它们与我的问题并不完全相同。

我正在使用JPA + Hibernate + Spring,我想做一些我不确定是否可能只是用config的事情。

我的域类具有或多或少复杂的关系。有许多元素与一个元素相关(例如,如果它是一棵树,许多元素都是一个元素的子级)。

像这样:

@Entity
class Foo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Foo parentNode;
    ...
}

这将得到一个表格,如:

Foo id    parent_id
1
2         1 
3         1

当我删除 id = 1 的行时,我想删除 id = 2 和 id = 3 的行(它可能是递归的,parent_id = 2 和 parent_id = 3 的元素也将被删除)。

对于某些限制,我只能在儿子方面与parent_id参考的关系。

我的问题是:是否可以使用JPA或Hibernate配置执行此操作,或者我是否需要执行一些递归函数来删除所有子项和所有父项?

我试过:

@OneToMany(name = "PARENT_ID", cascade = CascadeType.REMOVE)

我已经读过,也许使用Hibernate注释。

如果有人能给我一些线索,我现在就迷路了。

编辑 1

是否可以这样做:

@Entity
class Foo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name="PARENT_ID")
    private Foo parentNode;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "parentNode", cascade = CascadeType.REMOVE, orphanRemoval = true)
    private Set<Foo> childs = new LinkedHashSet<Foo>();
    ...
}

保持表原样,将 fk 提供给父级?我已经尝试过这个,但我不断得到同样的错误,fk限制违反了。

编辑 2

最后解决了:

@Entity
class Foo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Foo parentNode;

    @OneToMany(mappedBy = "parentNode", cascade = CascadeType.REMOVE)
    private Set<Foo> childs = new LinkedHashSet<Foo>();
    ...
}

即使我们通过仅引用父ID在BBDD中进行映射,这也是必需的。@OneToMany

现在,当我们删除带有子项的 Foo 时,它的子项也将被删除。

感谢您的时间和良好的建议!


答案 1

查看孤立删除选项:

@OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true)

下面是关于 和 的完整解释CascadeType.REMOVEorphanRemoval

祝你好运!


答案 2

JPA 中的关系始终是单向的,除非您在两个方向上都将父级与子级相关联。将 REMOVE 操作从父项级联到子项将需要父项到子项的关系(不仅相反)。

因此,在这里您需要将单向关系更改为双向关系。

有关更多详细信息,请参阅此链接。


推荐