【问题标题】:How to batch delete using bulkUpdate如何使用 bulkUpdate 批量删除
【发布时间】:2010-10-18 14:58:53
【问题描述】:

我有一个通用的用户/角色设置,带有一个 user_role 连接表。我正在尝试使用 Spring 的 HibernateTemplate 像这样批量删除所有锁定的用户:

getHibernateTemplate().bulkUpdate("delete from User where locked=?", true);

如果被删除的用户没有任何角色(user_role 表中没有记录),那么一切正常;但是,如果用户确实有角色记录,我会收到以下错误:

违反完整性约束 - 孩子 找到记录

角色在 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>();

那么即使用户有子记录,如何批量删除用户?谢谢!

【问题讨论】:

    标签: java hibernate spring orm


    【解决方案1】:

    根据 JPA 规范,批量删除操作不会级联到相关实体

    4.10 批量更新和删除操作

    批量更新和删除操作 适用于单个实体的实体 类(连同它的子类, 如果有)。只有一个实体摘要 模式类型可以在 FROM 或 UPDATE 子句。

    ...

    删除操作仅适用于 指定类的实体和 它的子类。 不会级联 给相关实体

    但是,我希望 JPA 提供程序能够处理连接表。可悲的是,Hibernate 没有,这已登录 HHH-1917。恐怕您将不得不依靠本机 SQL 自己清理连接表或在架构中使用级联外键。

    【讨论】:

      【解决方案2】:

      应用程序级级联(通过 hibernate 注释或 JPA 注释进行级联)仅在实际从 db 加载实际实体时才有效。当您使用带有 HQL 的 hibernate 模板时,您会注意到实体没有加载,而是直接将 HQL 转换为要执行的 SQL。

      如果要批量删除,必须先使用 HQL 查询删除所有相关表(即角色),然后再删除父表数据。

      【讨论】:

      • 从不是 Hibernate 实体的 user_role 表中删除记录的 HQL 是什么?我对 HQL 不是很熟悉。谢谢!
      • 您不能使用 HQL 来管理非映射实体。我建议你先映射 user_role 表;另一种方法是使用普通 SQL 从 user_role 表中删除。
      【解决方案3】:

      我不完全确定,因为我很难重现这个问题,但我认为您可能需要在 @ManyToMany 中添加级联

      @ManyToMany(cascade = CascadeType.ALL)
      

      【讨论】:

      • 我试过了,没用。我也试过@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN),也没用。
      • 不,根据 JPA 规范,批量删除不会级联到相关实体。
      【解决方案4】:

      由于您要批量删除具有 ManyToMany 相关项的内容,您首先必须删除关系(在连接表中),或者执行循环并为每个项手动删除(疯狂且过于繁重)。

      因此,由于 JPQL 不允许这样做,一种可能的方法是进行 本机 SQL 查询以删除相关表中所需的 id,然后进行批量删除。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-25
        • 1970-01-01
        • 2014-04-05
        • 1970-01-01
        相关资源
        最近更新 更多