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

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

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

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

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

有帮助吗?

解决方案

如果您在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)
    

其他提示

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

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

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

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

文档: Eclipse Wiki - 使用EclipseLink JPA Extensions - 第1.4章如何使用@PrivateOwned Annotation

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

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

根据 Java Persistence with Hibernate cascade orphan delete 不可用作为JPA注释。

JPA XML也不支持它。

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

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

orphanRemoval = true 无效。

我有同样的问题,我想知道为什么下面这个条件没有删除孤儿。当我执行命名删除查询时,Hibernate(5.0.3.Final)中的菜单列表未被删除:

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

然后我记得我不能使用命名删除查询,而是EntityManager。当我使用EntityManager.find(...)方法获取实体然后EntityManager.remove(...)删除它时,菜单也被删除了。

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

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top