休眠:通过一个查询删除所有子级 [英] Hibernate: Delete all children with one query

查看:76
本文介绍了休眠:通过一个查询删除所有子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR:是否可以将Hibernate配置为使用单个删除查询删除所有子对象?

TL;DR: Is it possible to configure Hibernate to delete all child objects using a single delete query?

完整问题:我在Hibernate 5.1中定义了以下父/子关联:

Full Question: I have the following parent/child association defined in Hibernate 5.1:

public class Parent {
  @OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", cascade = CascadeType.REMOVE)
  private List<Child> children;
}

public class Child {
  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "parent_id", nullable = false)
  private Parent parent;
}

当我删除父对象时,所有子对象都按预期方式删除,但每个子对象都被单独删除.在我的应用程序中,一个父级可能有成千上万的子级,因此出于性能原因,我需要使用单个查询一次将其全部删除.

When I delete the parent object, all of the child objects are deleted, as expected, but each one is deleted individually. In my application a parent could have many thousands of children, so for performance reasons I need to use a single query to delete them all at once.

可能的解决方法

  1. 在删除父级之前,手动执行我自己的HQL查询 DELETE FROM child WHERE parent_id =?.这里的缺点是我(和其他开发人员)必须记住调用该方法.另外,它本质上规避了级联删除.
  2. 允许级联删除在数据库级别进行.由于数据在幕后发生变化,我认为我需要记住手动对子集合进行 .clear()来防止Hibernate与数据库之间的差异.
  1. Manually execute my own HQL query, DELETE FROM child WHERE parent_id = ?, prior to deleting the parent. The downside here is that I (and any other developers) have to remember to call the method. Plus, it essentially circumvents the cascade delete.
  2. Allow the cascade delete to happen at the database level. Since data is changing behind the scenes, I assume I would need to remember to manually .clear() the child collection to prevent disparity between Hibernate and the database.


我看到以前的Hibernate版本具有


I see older versions of Hibernate used to have the concept of a one-shot delete but I cannot find anything similar in the documentation for the latest version. Has that functionality been removed?

推荐答案

  1. 说您删除父母.
  2. 如果其他表(例如GrandChild)具有外键约束带着孩子,每个孩子都有多个GrandChild记录,也需要删除.
  3. 多个生成的删除查询的原因是,Hibernate可以不知道是否有其他外键约束表,转到子"表.也可能有一些需要执行的回调方法,例如@PreRemove.这就是为什么从数据库中加载每个Child引用并分别删除它们的原因.
  4. 简而言之,如果您依靠Hibernate来管理您的实体,是默认行为.
  5. 要么在数据库中显式设置ON DELETE CASCADE,要么标记带注释的必需子实体@ org.hibernate.annotations.OnDelete,它会自动添加在架构生成过程中删除时"指向架构.以您的示例为例,

  1. Say you delete a Parent.
  2. If some other table, say GrandChild, has a foreign key constraint with Child, with each Child having multiple GrandChild records, they need to be removed too.
  3. The reason for multiple generated delete queries is, Hibernate can not know whether there are any foreign key constraints from other tables, to the "Child" table. Also there might be some call back methods that needs to executed such as @PreRemove. This is the reason why each Child reference is loaded from the database and removed individually.
  4. In short, if you depend on Hibernate to manage your entities, this is the default behavior.
  5. Either set the ON DELETE CASCADE in the data base explicitly, or mark the required Child entity with the annotation @org.hibernate.annotations.OnDelete, which automatically adds the "on delete" to schema during the schema generation. For your example it would be,

`@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", 
            cascade = CascadeType.REMOVE)    
 @org.hibernate.annotations.OnDelete(
            action = @org.hibernate.annotations.OnDeleteAction.CASCADE)
 private List<Child> children;

这篇关于休眠:通过一个查询删除所有子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆