我有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;
更新当我从用户删除角色并合并它然后尝试从base获取userByUsername时,它表明该用户没有此角色,但是当我尝试用户打开我的html页面时,它再次出现在列表中。
仔细阅读我之前的评论 - 我认为你已经将UserRole定义为关系的所有者(未使用mappedBy属性注释的那个!),因此将用户设置为UserRole而不是在User上设置UserRole可能会解决它。尝试为所需的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);
}
}
}
我会添加一个答案,因为我相信你错过了级联的要点。
您正在寻找孤儿清除。见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一起使用。你会更喜欢最终执行代码。