首页 > 解决方案 > 在未设置 CascadeType.REMOVE 时,Hibernate 在多对多关系中生成附加查询

问题描述

我有实体User

@Entity
@Table(name = "users")
public class User {
    (...)
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "users_roles",
            joinColumns = @JoinColumn(name = "user_id", nullable = false),
            inverseJoinColumns = @JoinColumn(name = "role_id", nullable = false)
    )
    private List<Role> roles;
}

Role和具有简单idname列的实体。

User并与 join tableRole多对多的关系users_roles

我创建了删除用户的方法:

public void remove(long userId) {
    Session session = getSession();

    //NativeQuery joinTableQuery = session.createNativeQuery("DELETE FROM users_roles ur WHERE ur.user_id = :userId");
    //joinTableQuery.setParameter("userId", userId);
    //joinTableQuery.executeUpdate();

    Query userQuery = session.createQuery("DELETE FROM User u WHERE u.id = :userId");
    userQuery.setParameter("userId", userId);
    userQuery.executeUpdate();
}

我故意注释掉了第一个 NativeQuery 以检查会发生什么。现在有趣的是 Hibernate 生成了两个查询:

问题:

为什么当我的实体没有设置关系时,Hibernate 会在users_roles(连接表)上生成额外的查询?我想我必须自己写(评论部分)。UserCascadeType.REMOVE@ManyToMany

标签: javaspringhibernatejpaspring-security

解决方案


您的User实体拥有与该实体的多对多关联Role。当您删除一个User时,Hibernate 也会自动从关联表中删除所有条目。但它不会将删除操作级联到Role实体。

你永远不应该CascadeType.REMOVE在多对多关联中使用。如果您删除一个实体,Hibernate 将删除所有关联的实体,即使它们仍被其他实体引用。我在我的博客上详细解释了这一点。

如果您要CascadeType.REMOVEroles关联上使用并删除 a User,Hibernate 将删除该Role引用的所有实体User。即使有其他User实体对象与这些Roles 相关联,它也会这样做。


推荐阅读