JPA CascadeType.ALL不会删除孤儿
题
我在使用带有以下映射的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,则必须先明确删除子元素,然后删除主记录以避免任何孤立记录。
执行顺序
- 获取要删除的主要行
- 获取子元素
- 删除所有子元素
- 删除主要行
- close session 醇>
使用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后,问题得到解决