Hibernate JPA许多更新记录

Hibernate JPA许多更新记录,hibernate,spring-boot,jpa,Hibernate,Spring Boot,Jpa,我有springboot2.1.3App。我使用的是Spring Security,我有两个实体User和Roles,如下所示: @Entity @Data @Table(name = "USER") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private Str

我有
springboot2.1.3
App。我使用的是
Spring Security
,我有两个实体
User
Roles
,如下所示:

@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;
}
现在让
SpringBoot
创建空的
数据库
,并假设添加一些默认记录:

现在考虑<代码>角色< /Cord>表最多包含2个角色:RoLyAdmin和RoLyAuthor。我设法用

角色添加新的
用户
,我设法用相应的
角色
删除
用户
(检索
用户
->从
用户
->迭代
角色
,并为每个角色删除
用户
->删除
用户

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);
roles_id  user_id
   2         1
   1         1
我尝试了所有方法,但都没有达到预期效果。获得的最佳结果是在
用户中添加两个
角色
(ROLE\u ADMIN和ROLE\u 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);
roles_id  user_id
   2         1
   1         1
在这种情况下,应用程序角色是分层的,
用户
最多可以有一个
角色
。我使用了
manytomy
关系,因为它是默认的
SpringSecurity
DB实现(我不知道我是否可以使用
OneToMany
关系)

我快疯了!你能帮我吗


谢谢

最好保存新列表或

User=userService.getByPk(Id);
//添加代码以删除用户的所有关联
//添加以下代码以分配新角色
列表角色=新的ArrayList();
roles.add(Role.Role\u用户);
user.setRoles(角色);
updateService.updateByPk(用户);

谢谢大家的回答。@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);

谢谢大家

问题是您有
角色。用户
用户
表中使用
mappedBy='users'
设置为拥有实体。只保留对拥有实体所做的更改。相反,请尝试将
mappedBy='Roles'
放在
角色
表中

当然,您应该使用
设置角色
而不是
列表
。列表是有序的,JPA/Spring数据将尝试保留顺序,这可能会造成性能开销。此外,在JPA中使用
列表
定义的多个XToMany关系可能会有问题

虽然您可能只需要为任何用户指定一个角色,但Spring Security定义并处理许多关系


JPA有一个更新--
persist
,既可以保存也可以更新。此外,对附加实体所做的更改将被持久化(更新)自动。

您尝试了什么?发布您的代码。您必须从管理员角色的用户中删除该用户,并将其添加到用户角色的用户中。是的,我知道
JPA
更新实体…如果
Entity
设置了主键
JPA
执行
更新,他将使用
save
方法自动执行该操作de>oherwise一个
insert
操作。我刚才对@Atul说,
JpaRepository
接口中不存在
updateByPk()
方法。
// 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);
User user = userRepository.findById(1L).get();
List<User> adminUsers = adminRole.getUsers(); // adminUser CONTAIN user of previous line
adminUsers.remove(user) // user IS NOT REMOVED, if debugging I select whole line and Watch result is false