JPA ManyToMany更新记录

时间:2019-11-19 22:19:04

标签: hibernate spring-boot jpa

我有SpringBoot 2.1.3应用。我使用的是Spring Security,而不是两个类似于以下内容的实体UserRoles

@Entity
@Data
@Table(name = "USER")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private boolean enabled;
    @ManyToMany(mappedBy = "users")
    private List<Roles> role;
}

@Entity
@Data
@Table(name = "ROLES")
public class Roles {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private Role ruolo;
    @ManyToMany
    private List<User> users;
}

角色是一个简单的enum,如下所示:

public enum Role {
   ROLE_ADMIN,
   ROLE_USER;
}

现在让SpringBoot创建空的database并假设添加一些默认记录:

enter image description here

现在,请考虑Roles表最多包含两个角色: ROLE_ADMIN ROLE_USER 。我设法用User添加新的Roles,我设法用相应的User删除Role(从User->获取Roles User->迭代Roles,然后每删除一次User->删除User

User user = userService.getByPk(Id);

List<Roles> roles = user.getRoles(); // this list size should be always 1
for (Rolesr : roles) {
   r.getUsers().remove(user);
}

utenteService.deleteByPk(opeId);

将同时删除User条记录和相应的Roles_User条记录。

不能做的 CHANGE 的用户角色。如图所示,我有一个User ROLE_ADMIN < / em> Roles

为此,我想将Roles的{​​{1}}从 ROLE_ADMIN 更改为 ROLE_USER !该函数应如下修改User

Roles_User

我已经尝试了所有方法,但是没有任何效果。获得的最佳结果是将两个roles_id user_id 2 1 (ROLE_ADMIN和ROLE_USER)添加到Roles

User

在该应用程序中,ROLES是分层的,一个roles_id user_id 2 1 1 1 最多可以有一个User。我使用了Role关系,因为它是默认的ManyToMany数据库实现(我不知道我是否可以使用SpringSecurity关系)。

我要疯了!你能帮我吗?

谢谢

3 个答案:

答案 0 :(得分:0)

最好保存新列表或Check this link

User user = userService.getByPk(Id);
// Add your code to delete all association of an user
// Add below code to assign new role
List<Roles> roles = new ArrayList<>();
roles.add(Role.ROLE_USER);
user.setRoles(roles);

utenteService.updateByPk(user);

答案 1 :(得分:0)

非常感谢您的回答。 @Atul Jain我已经尝试了您的代码,但是如果不进行级联,肯定无法正常工作。

最后我设法做到了,这是解决方案:

// getting my User and removing all his roles (max one)
User user = userRepository.findById(1L).get();
user.getRoles().clear();

// get ROLE_ADMIN Role
Roles adminRole = rolesRepository.findById(1L).get();

// get all users with ROLE_ADMIN role and removing my user
List<User> adminUsers = adminRole.getUsers();
adminUsers.remove(user); 

List<Roles> roles = new ArrayList<>();
// get ROLE_USER Role and adding my User
Roles role = rolesRepository.findById(2L).get();
role.getUsers().add(user);
roles.add(role);

user.setRoles(roles);

userRepository.save(user);
rolesRepository.save(adminRole);
rolesRepository.save(role);

我想记住JPA接口在他的update中没有Repository方法,在这种情况下我无法实例化Role,因为此{ {1}}应该被视为table,在应用程序启动时填写,并且永远不会(可能很少.. :))更新。

因此,我必须提取要添加的typological

无论如何,有人可以告诉我为什么:

Role

谢谢大家

答案 2 :(得分:0)

问题是您在Roles.users表中将mappedBy='users'设置为拥有实体Users。仅保留对拥有实体所做的更改。而是尝试将mappedBy='roles'放在Roles表中。

当然,您应该使用Set<Role> role而不是List。列表已排序,并且JPA / Spring-Data将尝试保留排序,这可能会增加性能。另外,在JPA中用Lists定义的多个XToMany关系可能会出现问题。

虽然您可能只希望对任何用户使用一个角色,但是Spring Security定义并处理了ManyToMany关系。

JPA有一个更新-persist,它既可以保存也可以更新。另外,对附加实体所做的更改将自动保留(更新)。