Hibernate 在Spring数据中删除关联@ManyToMany并不总是有效

Hibernate 在Spring数据中删除关联@ManyToMany并不总是有效,hibernate,spring-data-jpa,Hibernate,Spring Data Jpa,我不熟悉Spring数据, 我试图处理(@manytoman)用户与来自枚举的角色的关联(编辑:我删除了增加复杂性的枚举,但没有使用)。 我对向用户添加角色没有问题,但删除角色更是一个问题 我读了很多关于映射多个关联的最佳方法的书 我的用户类: @实体 @吸气剂 @塞特 @AllArgsConstructor @诺尔格构装师 公共类用户{ @身份证 @GeneratedValue(策略=GenerationType.IDENTITY) 私人长id; @NotNull @电子邮件 私人字符串电子邮

我不熟悉Spring数据, 我试图处理(@manytoman)用户与来自枚举的角色的关联(编辑:我删除了增加复杂性的枚举,但没有使用)。 我对向用户添加角色没有问题,但删除角色更是一个问题

我读了很多关于映射多个关联的最佳方法的书

我的用户类:

@实体
@吸气剂
@塞特
@AllArgsConstructor
@诺尔格构装师
公共类用户{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@NotNull
@电子邮件
私人字符串电子邮件;
@ManyToMany(cascade={CascadeType.MERGE})
@JoinTable(name=“用户角色”,
joinColumns=@JoinColumn(name=“user\u id”),
inverseJoinColumns=@JoinColumn(name=“role\u id”))
私有集角色=新HashSet();
public void addRole(角色角色){
this.roles.add(角色);
role.getUsers().add(此);
}
公共无效删除OLE(角色){
this.roles.remove(角色);
role.getUsers().remove(此);
}
}
我的角色课:

@实体
@吸气剂
@塞特
@AllArgsConstructor
@诺尔格构装师
公共阶级角色{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
专用字符串指定;
@许多(mappedBy=“角色”)
private Set users=new HashSet();
公共角色(字符串指定){
这个名称=名称;
}
}
还有我的测试:

publicstaticvoidmain(字符串[]args){
run(LibraryApiWebApplication.class,args);
}
@凌驾
公共无效运行(字符串…参数)引发异常{
BCryptPasswordEncoder编码器=新的BCryptPasswordEncoder();
角色用户=新角色(RoleDesignation.user);
角色管理员=新角色(RoleDesignation.admin);
角色存储。保存(用户);
角色存储。保存(管理);
用户user1=新用户(“***@hotmail.fr”,encoder.encode(“1234”),“***”,“***”,User);
User user2=新用户(“*****@gmail.com”、encoder.encode(“1234”)、“*****”、“用户”);
user1.addRole(admin);
userRepository.save(user1);
userRepository.save(user2);
user1.removole(admin);
userRepository.save(user1);
user2.addRole(admin);
userRepository.save(user2);
user2.removole(admin);
userRepository.save(user2);
}
}
这一个有效(编辑:清除关联后,它不再有效):

休眠执行删除操作

但第二个没有:

        user2.removeRole(admin);
        userRepository.save(user2);
hibernate只进行选择,不进行删除。 我试图在日志中找到它是否是一个“未计划的实体删除”,但我找不到它(顺便说一句,我从来没有正确处理过这个问题)


感谢您的时间!

这是一种非常好的方法,可以通过添加和删除方法保持关系(代码和数据库)的同步。但是,这意味着您需要适当的方法来处理
hashCode
equals
。在中,Vlad Mihalcea很好地描述了最佳和最简单的方法

在您的情况下,您必须添加以下代码

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof User)) return false;
    User that = (User) o;
    return Objects.equals(this.getId(), that.getId());
}

@Override
public int hashCode() {
    return 56;
}

然后,您必须更改
Role

的类,尝试记录您的JPA语句。然后,您将更好地了解发生了什么。尝试使用调试器查看何时执行了哪些查询。(当然,您可以使用详细信息更新帖子。)实际上,我在application.properties
spring.jpa.show sql=true,logging.level.org.hibernate.sql=DEBUG,logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
中有这些参数,我看不到任何东西能告诉我发生了什么。我只看到一些正在执行的select请求,这就是answer、 我读了很多关于这些文章的文章,我不得不承认我对此了解不多。我试过你写的代码,但都是一样的。一个问题,为什么hashCode返回56?
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof User)) return false;
    User that = (User) o;
    return Objects.equals(this.getId(), that.getId());
}

@Override
public int hashCode() {
    return 56;
}