JPA CascadeType.ALL不会删除孤儿

时间:2008-11-20 17:31:33

标签: java hibernate orm jpa jpa-2.0

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

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

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

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

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

11 个答案:

答案 0 :(得分:154)

如果您在Hibernate中使用它,则必须明确定义注释CascadeType.DELETE_ORPHAN,它可以与JPA CascadeType.ALL一起使用。

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

执行顺序

  1. 获取要删除的主要行
  2. 获取子元素
  3. 删除所有子元素
  4. 删除主要行
  5. close session
  6. 使用JPA 2.0,您现在可以使用选项 orphanRemoval = true

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

答案 1 :(得分:111)

如果您使用的是JPA 2.0,现在可以使用orphanRemoval=true注释的@xxxToMany属性来删除孤儿。

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

答案 2 :(得分:43)

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

答案 3 :(得分:12)

如果您将JPA与EclipseLink一起使用,则必须设置 @PrivateOwned 注释。

文档:Eclipse Wiki - Using EclipseLink JPA Extensions - Chapter 1.4 How to Use the @PrivateOwned Annotation

答案 4 :(得分:7)

您可以使用@PrivateOwned删除孤儿 e.g

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

答案 5 :(得分:4)

根据Java Persistence with Hibernate级联孤儿删除不可用作JPA注释。

JPA XML也不支持它。

答案 6 :(得分:4)

我只是找到了这个解决方案,但在我的情况下它不起作用:

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

orphanRemoval = true 无效。

答案 7 :(得分:2)

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

删除 targetEntity = MyClass.class ,效果很好。

答案 8 :(得分: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(...)删除它时,菜单也被删除了。

答案 9 :(得分:1)

对于记录,在JPA2之前的OpenJPA中,它是@ElementDependant。

答案 10 :(得分:0)

我正在使用一对一映射,但是孩子没有被删除JPA正在提供外键违规

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