Java 冬眠不';t使用合并或更新更新实体

Java 冬眠不';t使用合并或更新更新实体,java,spring,hibernate,Java,Spring,Hibernate,我有User和UserRole类。我想从用户中删除角色并对其进行更新 这是我的deleteRole方法: public void deleteRole(String username, String role) { User user = userDao.findByUserName(username); Set<UserRole> userRoles = user.getUserRole(); for (UserRole t

我有User和UserRole类。我想从用户中删除角色并对其进行更新

这是我的deleteRole方法:

public void deleteRole(String username, String role) {
     User user = userDao.findByUserName(username);
            Set<UserRole> userRoles = user.getUserRole();
            for (UserRole tempRole: userRoles) {
                if (tempRole.getRole().equals(role)){
                    userRoles.remove(tempRole);
                }
            }
            user.setUserRole(userRoles);
      updateUser(user);
}
我尝试了更新、合并、保存或更新,但没有任何更改。我仍然有相同的角色

用户实体

@Entity
@Table(name = "USERS")
public class User {
    @Id
    @Column(name = "USERNAME", nullable = false, unique = true)
    private String username;

@Column(name = "PASSWORD", nullable = false)
private String password;

@Transient
private String confirmPassword;

@Column(name = "ENABLED", nullable = false)
private boolean enabled = true;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.EAGER)
private Set<UserRole> userRole = new HashSet<>();
更新
当我从用户中删除角色并将其合并,然后尝试从base中获取userByUsername时,这表明该用户没有此角色,但当我尝试与用户一起打开html页面时,它再次出现在列表中。

详细说明我之前的评论-我认为您已将UserRole定义为关系的所有者(没有用mappedBy属性注释的那个!),因此将用户设置为UserRole而不是将UserRole设置为user可能会解决这个问题。 尝试将用户成员设置为所需的userRole,而不是相反

    public void deleteRole(String username, String role) {
    User user = userDao.findByUserName(username);
    Set<UserRole> userRoles = user.getUserRole();
    for (UserRole tempRole: userRoles) {
        if (tempRole.getRole().equals(role)){
            tempRole.setUser(null);
            sessionFactory.getCurrentSession().merge(tempRole);
        }
    }
}
public void delete角色(字符串用户名,字符串角色){
User=userDao.findByUserName(用户名);
设置userRoles=user.getUserRole();
for(UserRole tempRole:userRoles){
if(tempRole.getRole().equals(role)){
tempRole.setUser(null);
sessionFactory.getCurrentSession().merge(tempRole);
}
}
}

我将添加一个答案,因为我相信您没有理解cascade的要点

您正在寻找孤儿移除。 看

另请参见-Hibernate和JPA2.0的旧版本之间的语法不同

此外,您依赖于jdbc自动提交,而不是使您的方法
@Transactional
。因此,您的实体在使用find检索后立即分离。然后使用merge重新附加实体。这没有意义。 最重要的是,Hibernate使用脏检查,所以您不需要对会话执行任何操作来执行更新。它们将在刷新会话时运行

只要您想依靠cascade删除您的用户角色,以上所有内容都适用。
您还可以检索您要查找的对象,并将Session.remove与UserRole一起使用。您更希望最终得到性能更好的代码。

请共享您的用户和UserRole实体。与实体一起更新帖子。尝试将您的方法标记为@Transactional,并同时删除User.setUserRole和update。对此不确定-但我认为您是正确的我已将UserRole定义为关系的所有者,因此将用户设置为UserRole而不是将UserRole设置为user可能会解决此问题。我不明白您的确切意思。您能提供一个示例吗?我已编辑以添加您的代码示例的修改版本。我无法对其进行测试或正确模拟您的环境现在,但我希望我的观点得到了理解。简单地从UserRole端而不是用户端删除关联。谢谢。它可以工作。据我所知,它可以与UserRole表一起工作,而不是与User一起工作?它是从UserRole表中删除记录,还是留下一个空的记录-“myRole”?我测试过,它在表中留下空记录,就像User:null-rol一样e:‘myRole’。我可以让它从表中完全删除记录吗?当然,您可以使用entitymanager的“remove”或使用Spring数据存储库的“delete”。
@Entity
@Table(name = "USER_ROLES", uniqueConstraints = @UniqueConstraint(
        columnNames = { "ROLE", "USERNAME" }))
public class UserRole {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "user_role_id",
            unique = true, nullable = false)
    private Integer userRoleId;

    @Column(name = "ROLE")
    private String role;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "USERNAME")
    private User user;
    public void deleteRole(String username, String role) {
    User user = userDao.findByUserName(username);
    Set<UserRole> userRoles = user.getUserRole();
    for (UserRole tempRole: userRoles) {
        if (tempRole.getRole().equals(role)){
            tempRole.setUser(null);
            sessionFactory.getCurrentSession().merge(tempRole);
        }
    }
}