Hibernate不会通过合并或更新来更新实体

时间:2019-04-22 10:53:44

标签: 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 tempRole: userRoles) {
                if (tempRole.getRole().equals(role)){
                    userRoles.remove(tempRole);
                }
            }
            user.setUserRole(userRoles);
      updateUser(user);
}

这是我的updateUser方法:

 public void update(User user) {
       sessionFactory.getCurrentSession().merge(user);
    }

我尝试了更新,合并,saveOrUpdate,但没有任何变化。我仍然扮演着相同的角色。

用户实体

@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<>();

这是userRole实体

@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;

更新 当我从用户中删除角色并合并它,然后尝试从基础中获取userByUsername时,它表明该用户没有此角色,但是当我尝试与用户打开html页面时,它再次出现在列表中。

2 个答案:

答案 0 :(得分:1)

在此之前,我先详细介绍一下我的评论-我认为您已将UserRole定义为关系的所有者(未使用mapedBy属性进行注释的人!),因此将用户设置为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);
        }
    }
}

答案 1 :(得分:1)

我会添加一个答案,因为我相信您缺少级联的要旨。

您正在寻找孤儿。 参见https://www.baeldung.com/delete-with-hibernate

另请参阅jpa removing item from list-较早版本的Hibernate和Jpa 2.0之间的语法不同

此外,您依赖于jdbc自动提交,而不是使方法@Transactional。因此,您的实体在使用find检索之后即被分离。然后,您通过合并重新附加实体。这是没有道理的。 最重要的是,Hibernate使用脏检查,因此您无需在Session上执行任何操作即可执行更新。它们将在刷新会话后运行。

以上所有内容都适用,只要您要依靠层叠来删除userRole。 您也可以检索所要查找的对象,然后将Session.remove与UserRole一起使用。您会更喜欢以bettr执行代码结束。