JPA CascadeType.ALL不会删除孤儿


132

我在使用带有以下映射的JPA删除孤立节点时遇到问题

@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner")
private List<Bikes> bikes;

我遇到了孤立角色挂在数据库周围的问题。

我可以使用org.hibernate.annotations.Cascade特定于注释的Hibernate标记,但是显然我不想将解决方案绑定到Hibernate实现中。

编辑:似乎JPA 2.0将包括对此的支持。

Answers:


164

如果将它与Hibernate一起使用,则必须显式定义批注CascadeType.DELETE_ORPHAN,该批注可与JPA结合使用CascadeType.ALL

如果您不打算使用Hibernate,则必须先明确删除子元素,然后再删除主记录,以避免出现任何孤立记录。

执行顺序

  1. 获取要删除的主行
  2. 获取子元素
  3. 删除所有子元素
  4. 删除主行
  5. 闭门会议

在JPA 2.0中,您现在可以使用选项orphanRemoval = true

@OneToMany(mappedBy="foo", orphanRemoval=true)

3
谢谢,我最终选择了这条路线,我认为这对于JPA规范来说有点过高。
Paul Whelan

13
JPA 2.0标准现在具有deleteOrphan作为@OneToMany的属性如果您使用的是最新的休眠模式,则可以执行@OneToMany(...,deleteOrphan = true)
jomohke 2010年

我刚更新子元素时执行顺序是什么?孤记录会被删除吗?
jAckOdE 2014年

113

如果使用的是JPA 2.0,则现在可以使用批注的orphanRemoval=true属性@xxxToMany来删除孤立对象。

实际上,CascadeType.DELETE_ORPHAN已在3.5.2-Final中弃用。


6
实际上,我认为orphanRemoval = true表示其他含义,即,当我从父对象的集合中删除对象时,将其删除。参见download.oracle.com/javaee/6/tutorial/doc/bnbqa.html#giqxy
Archie 2010年

请通过Archie的链接进行操作。
Jigar Shah 2012年

4
orphanRemoval = true也不起作用。它必须用旧方法完成。
Joe Almore 2013年

45
╔═════════════╦═════════════════════╦═════════════════════╗
   Action      orphanRemoval=true    CascadeType.ALL   
╠═════════════╬═════════════════════╬═════════════════════╣
   delete         deletes parent      deletes parent   
   parent         and orphans         and orphans      
╠═════════════╬═════════════════════╬═════════════════════╣
   change                                              
  children      deletes orphans         nothing        
    list                                               
╚═════════════╩═════════════════════╩═════════════════════╝

1
如果我拥有cascade = CascadeType.ALL, orphanRemoval = false并删除父母,该怎么办?即使我已经明确告诉“不要”,它也会删除孩子吗?
izogfif


7

您可以使用@PrivateOwned删除孤儿,例如

@OneToMany(mappedBy = "masterData", cascade = {
        CascadeType.ALL })
@PrivateOwned
private List<Data> dataList;

5
谢谢@reshma,应该注意@PrivateOwned是eclipselink JPA扩展。
保罗·惠兰

5

我只是找到此解决方案,但对我而言却行不通:

@OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true) 

orphanRemoval = true无效。


1
在更改生效之前,我需要清理和构建。
maralbjo 2012年

哇,我一直在寻找一个小时,以了解为什么在我的ManyToOne上添加CascadeType.ALL并不是级联删除操作。清洗和建造,它的工作原理。谢谢@maralbjo。
Andrew Mairose 2015年


2

我遇到了同样的问题,我想知道为什么下面的这种情况没有删除孤儿。当我执行一个命名的删除查询时,在Hibernate(5.0.3.Final)中没有删除餐具列表:

@OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Dish> dishes = new ArrayList<>();

然后,我想起了我一定不能使用命名删除查询,而是EntityManager。当我使用该EntityManager.find(...)方法获取实体然后EntityManager.remove(...)将其删除时,餐具也被删除了。


2

只是@OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true)

删除targetEntity = MyClass.class,它很好用。



0

我正在使用一对一映射,但是未删除子级JPA违反了外键

使用orphanRemoval = true后,问题得到解决


@OneToOne(cascade = CascadeType.ALL,orphanRemoval = true)@JoinColumn(name =“ CHILD_OID”)private子级孩子;
vipin chauhan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.