当未设置CascadeType.REMOVE时,Hibernate在ManyToMany关系中生成其他查询

时间:2019-03-25 22:32:52

标签: java spring hibernate jpa spring-security

我有实体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列。

UserRole与联接表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生成了两个查询:

  • 休眠:从users_roles中删除(user_id)所在的位置(从其中id =?的用户中选择ID)
  • 休眠:从id =?
  • 的用户删除

问题:

为什么当我的users_roles实体没有在User关系上设置CascadeType.REMOVE时,Hibernate在@ManyToMany(联接表)上生成附加查询?我以为我必须自己写(注释部分)。

1 个答案:

答案 0 :(得分:0)

您的User实体拥有Role实体的many-to-many association。当您删除User时,Hibernate也会自动从关联表中删除所有条目。但它不会将删除操作级联到Role实体。

永远不要在多对多关联上使用CascadeType.REMOVE。如果删除一个实体,则Hibernate也会删除所有关联的实体,即使它们仍被其他实体引用。我对on my blog进行了详细说明。

如果您要在CascadeType.REMOVE关联上使用roles并删除User,则Hibernate会删除该Role引用的所有User实体。即使存在与这些User相关联的其他Role实体对象,也会这样做。