代码之家  ›  专栏  ›  技术社区  ›  SamS

如何使用BulkUpdate批量删除

  •  7
  • SamS  · 技术社区  · 15 年前

    我有一个通用的用户/角色设置,带有一个用户角色联接表。我尝试使用Spring的HibernateTemplate批量删除所有锁定的用户,如下所示:

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

    如果要删除的用户没有任何角色(用户角色表中没有记录),则一切正常;但是,如果用户确实有角色记录,则会出现以下错误:

    违反完整性约束-子级 记录发现

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

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

    4 回复  |  直到 15 年前
        1
  •  8
  •   Pascal Thivent    14 年前

    批量删除操作不层叠到 相关实体 根据JPA规范:

    4.10批量更新和删除操作

    批量更新和删除操作 应用于单个实体的实体 类(及其子类, 如果有的话)。只有一个实体摘要 不能在中指定架构类型 FROM或UPDATE子句。

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

    但是,我希望JPA提供程序处理联接表。很遗憾,Hibernate没有,这是登录的 HHH-1917 .恐怕您必须依靠本机SQL自己清理联接表,或者在模式中使用级联外键。

        2
  •  2
  •   Miguel Ping    15 年前

    应用程序级级联(通过Hibernate注释或JPA注释级联)仅在实际实体实际从数据库加载时才起作用。当将hibernate模板与hql一起使用时,您会注意到实体没有加载,hql直接转换为要执行的sql。

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

        3
  •  0
  •   Greg Noe    15 年前

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

    @ManyToMany(cascade = CascadeType.ALL)
    
        4
  •  0
  •   Cyril N.    13 年前

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

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