这是关于 Hibernate 生成的关于在多对多映射下删除一个关系的 sql 的问题,而不是“级联”问题。
我使用 JPA 2 和 hibernate 作为它的实现。
我有两个模型,用户和角色。一个用户可以有多个角色,一个角色可以有多个用户,所以它们是多对多映射:
@Entity
class User{
@Id Long id;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinTable(name = "user_role", inverseJoinColumns = @JoinColumn(name = "role_id"),
joinColumns = @JoinColumn(name = "user_id"))
private List<Role> roles;
}
@Entity
class Role{
@Id Long id;
@ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REFRESH, mappedBy = "roles")
private List<User> users;
}
并且映射工作良好,休眠自动为此映射创建三个表
table user
table role
table user_role
现在问题来了,我想要的只是从一个用户中删除一个角色(不是删除一个用户或一个角色,只是一个用户和一个角色之间的一种关系,意味着只需要从表中删除一条记录user_role
)。这是我尝试过的代码:
public void removeOneRoleFromUser(long userId, long roleId){
User user = userService.getById(userId);
Role role = roleService.getById(roleId);
user.getRoles().remove(role); //here
userService.update(user);
}
当我执行此代码时,它确实从用户中删除了该角色。但是当我检查hibernate为其生成的sql时,这不是我所期望的,hibernate生成的sql是:
delete from user_role where user_id = {userId}
insert into user_role values({user_id}, {role_id_not_removed})
...
insert into user_role values({user_id}, {another_role_id_not_removed})
所以要从一个用户中删除一个角色,hibernate首先从用户中删除所有角色,然后将那些不应该删除的角色一一添加回用户。
而我所期望的只是一个 sql 语句归档它:
delete from user_role where user_id = {userId} and role_id = {role_id}
我知道还有其他一些方法可以存档,比如引入另一个UserRoleMapping
映射到表的实体user_role
,然后直接删除一个 UserRoleMapping 实例将从一个用户中删除一个角色;但我想知道是否有任何解决方案可以通过当前解决方案获得预期。