Hibernate orphanRemoval可以使用独特的约束吗?

时间:2018-06-10 18:36:42

标签: java hibernate jpa

我有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表在U__ROLE_ID__CODE__PRIVILEGErole_id列上具有唯一约束code

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

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

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

没有约束,一切正常。但是,删除约束似乎不是一个完美的解决方案。

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

复制项目可用here

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:-1)

// 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);
}