【问题标题】:Can Hibernate orphanRemoval work with unique constraints?Hibernate orphanRemoval 可以使用独特的约束吗?
【发布时间】:2018-11-20 01:33:43
【问题描述】:

我有 2 个实体:RolePrivilege。一个角色有很多特权。实体如下所示:

@Entity
public class Role {

    private Integer id;
    private String code;
    @OneToMany(mappedBy = "role", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Privilege> privileges;
}

@Entity
public class Privilege {

    private Integer id;
    private String code;
    @ManyToOne
    @JoinColumn(name = "role_id")
    private Role role;
}

privilege 表在 role_idcode 列上具有唯一约束 U__ROLE_ID__CODE__PRIVILEGE

我有一个更新角色的 REST 端点。此更新还包括更改分配给角色的权限:

private static void setPrivileges(Set<Privilege> existing, Set<Privilege> privileges) {
    existing.clear();
    existing.addAll(privileges);
}

由于某种原因,当我更新角色时,Hibernate 首先将新权限插入权限表,然后才删除孤立的权限。因此,如果新的权限列表包含旧列表中的至少一个权限,则更新失败并违反U__ROLE_ID__CODE__PRIVILEGE 约束。

没有约束一切正常。但是,移除约束看起来并不是一个完美的解决方案。

是否可以更改 Hibernate 处理角色-权限关系更新的顺序,以便首先删除孤立的权限,然后才插入新的权限?

复刻项目可here.

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    您可能需要重新访问CascadeType。如果您希望在删除角色时传播删除,您将需要使用 CasadeType.REMOVE

    因为您已将其设置为CascadeType.ALL,您会注意到对Role 的每次更新/持久性尝试都会传播到Privilege。因此与这些表的唯一约束相冲突。

    【讨论】:

      【解决方案2】:
      // You can flush:
      
      private static void setPrivileges(Set<Privilege> existing, Set<Privilege> privileges) {
          existing.clear();
          repository.flush(); // queues delete statements before subsequent operations
          existing.addAll(privileges);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-03-05
        • 2019-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-09
        • 2016-05-14
        相关资源
        最近更新 更多