java 如何使用bulkUpdate批量删除
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/735201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to batch delete using bulkUpdate
提问by SamS
I have a common User / Role setup, with a user_role join table. I'm trying to use Spring's HibernateTemplate to mass delete all locked users like this:
我有一个通用的用户/角色设置,带有一个 user_role 连接表。我正在尝试使用 Spring 的 HibernateTemplate 批量删除所有锁定的用户,如下所示:
getHibernateTemplate().bulkUpdate("delete from User where locked=?", true);
If the user being deleted does not have any roles (no record in the user_role table), then everything goes fine; however if the user does have a role record, I'm getting the following error:
如果被删除的用户没有任何角色(user_role 表中没有记录),那么一切正常;但是,如果用户确实有角色记录,则会出现以下错误:
integrity constraint violated - child record found
违反完整性约束 - 找到子记录
Roles are defined in User.java like this:
角色在 User.java 中定义如下:
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<Role>();
So how can I batch delete users even if a user has child records? Thanks!
那么即使用户有子记录,我如何批量删除用户?谢谢!
回答by Pascal Thivent
Bulk delete operations are not cascaded to related entitiesas per the JPA specification:
根据 JPA 规范,批量删除操作不会级联到相关实体:
4.10 Bulk Update and Delete Operations
Bulk update and delete operations apply to entities of a single entity class (together with its subclasses, if any). Only one entity abstract schema type may be specified in the FROM or UPDATE clause.
...
A delete operation only applies to entities of the specified class and its subclasses. It does not cascade to related entities.
4.10 批量更新和删除操作
批量更新和删除操作适用于单个实体类(及其子类,如果有)的实体。在 FROM 或 UPDATE 子句中只能指定一种实体抽象模式类型。
...
删除操作仅适用于指定类及其子类的实体。它不会级联到相关实体。
However, I'd expect the JPA provider to deal with join tables. Sadly, Hibernate doesn't and this is logged in HHH-1917. I'm afraid you'll have to fall back on native SQL to clean up the join table yourself or to use cascading foreign keys in the schema.
但是,我希望 JPA 提供程序能够处理连接表。遗憾的是,Hibernate 没有,这记录在HHH-1917 中。恐怕您将不得不依靠本机 SQL 来自己清理连接表或在架构中使用级联外键。
回答by Miguel Ping
Application-level cascading (cascading through hibernate annotations or JPA annotations) only work if the actual entity is actually loaded from the db. When you use the hibernate template with HQL, you'll notice that the entities are not loaded, and the HQL is directly converted to SQL to be executed.
应用程序级级联(通过休眠注释或 JPA 注释级联)仅在实际实体实际从数据库加载时才有效。当你在HQL中使用hibernate模板时,你会发现实体没有被加载,HQL直接转换成SQL来执行。
If you want to batch delete you have to use an HQL query to delete all relevant tables (ie roles) before deleting the parent table data.
如果要批量删除,则必须在删除父表数据之前使用 HQL 查询删除所有相关表(即角色)。
回答by Greg Noe
I'm not entirely sure because it's hard for me to recreate this problem, but I think you might need to add a cascade to your @ManyToMany
我不完全确定,因为我很难重现这个问题,但我认为您可能需要向 @ManyToMany 添加级联
@ManyToMany(cascade = CascadeType.ALL)
回答by Cyril N.
Since you want to bulk delete something that have a ManyToMany related items, you first have to delete the relation (in the join table), or do a loop and for each item, delete manually (insane and too much heavy).
由于您想批量删除具有 ManyToMany 相关项目的内容,您首先必须删除关系(在连接表中),或者执行循环并为每个项目手动删除(疯狂且过于沉重)。
So, since JPQL does not allow to do it, a possible way is to make a native SQL queryfor deleting the id you want in the related table, and then, do the bulk delete.
因此,由于 JPQL 不允许这样做,一种可能的方法是进行本机 SQL 查询以删除相关表中所需的 id,然后进行批量删除。

