jpa级联删除的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jpa级联删除的问题相关的知识,希望对你有一定的参考价值。

现在有三张表SingleDisk , DISKPACK , DISK_DISKPACK 其中C是A表和B的关联的中间表,现在我想删除DISKPACK 表里的数据,DISK_DISKPACK 表数据要删除,但BSingleDisk 所对应的数据不删除,请问下这个要怎么配置?代码如下:
@OneToMany(mappedBy="diskPack",cascade=CascadeType.PERSIST,CascadeType.REMOVE,fetch=FetchType.LAZY)
private List<SingleDisk> singleDisks=new ArrayList<SingleDisk>();

@ManyToOne(optional=true,fetch=FetchType.LAZY)
@JoinTable(name="DISK_DISKPACK",joinColumns = @JoinColumn(name = "DISKID",referencedColumnName="objectId"), inverseJoinColumns = @JoinColumn(name = "DISKPACKID",referencedColumnName="objectId"))
private DiskPack diskPack;
请问要怎么配置才能实现这个效果,目前是删除表DISKPACK的数据,会把 SingleDisk这个表的数据删除,求助。

参考技术A @OneToMany(mappedBy="category", cascade=CascadeType.ALL,fetch=FetchType.EAGER )

cascade的注解作用是:category对象的增删改关联到当前类所在对象
fetch是读取关联查询是否lazy

JPA + Hibernate + Spring + OneToMany 删除级联

【中文标题】JPA + Hibernate + Spring + OneToMany 删除级联【英文标题】:JPA + Hibernate + Spring + OneToMany delete cascade 【发布时间】:2014-11-16 01:21:16 【问题描述】:

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

我正在使用 JPA + Hibernate + Spring,我想做一些我不确定是否可以仅使用配置的事情。

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

类似:

@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>();
    ...

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

现在当我们删除一个带有子元素的 Foo 时,它的子元素也会被删除。

感谢您的宝贵时间和建议!

【问题讨论】:

【参考方案1】:

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

所以这里需要将单向关系改为双向。

更多详情请参考this link.

【讨论】:

谢谢,但我在 ManyToOne 方面需要这个,因为我没有 OneToMany 方式。这有没有可能?谢谢 那么如果我不能有这个双向,我需要做一些递归过程吗?谢谢 是的,你必须参考fruzenshtein.com/bidirectional-many-to-one-association 我看过这个链接:java2s.com/Code/Java/JPA/ManyToOneCascadeRemove.htm 他们确实删除了多对一的关系,但这似乎不起作用。谢谢【参考方案2】:

看orphanRemoval选项:

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

这里是complete explication 关于CascadeType.REMOVEorphanRemoval

祝你好运!

【讨论】:

以上是关于jpa级联删除的问题的主要内容,如果未能解决你的问题,请参考以下文章

JPA/Hibernate 级联删除不起作用

JPA:单向多对一和级联删除

为啥手动定义的 Spring Data JPA 删除查询不会触发级联?

JPA Hibernate - 数据库和注释中的级联删除

Spring data JPA:如何启用级联删除而不引用父级中的子级?

hibernate 级联删除