[英]JPA ManyToMany updating record
我有SpringBoot 2.1.3
應用程序。 我使用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;
}
Role是一個簡單的enum
,如下所示:
public enum Role {
ROLE_ADMIN,
ROLE_USER;
}
現在讓SpringBoot
創建空database
並假設添加一些默認記錄:
現在考慮Roles
表將包含最多 2 個角色: ROLE_ADMIN和ROLE_USER 。 我設法使用Roles
添加新User
,我設法刪除具有相應Role
的User
(檢索User
-> 從User
獲取Roles
-> 迭代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
記錄。
我不能做的是改變用戶角色。正如我們在圖片中看到的那樣,我有一個具有ROLE_ADMIN Roles
的User
。
我想將此User
的Roles
從ROLE_ADMIN 更改為ROLE_USER ! function 應修改Roles_User
如下:
roles_id user_id
2 1
我已經嘗試了一切,但沒有按預期工作。 獲得的最佳結果是將兩個Roles
(ROLE_ADMIN 和 ROLE_USER)添加到User
:
roles_id user_id
2 1
1 1
在該應用程序中,角色是分層的,一個User
最多可以擁有一個Role
。 我使用了ManyToMany
關系,因為它是默認的SpringSecurity
DB 實現(我不知道我是否可以使用OneToMany
關系)。
我要瘋了? 你能幫助我嗎?
謝謝
更好,保存新列表或檢查此鏈接
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);
謝謝大家的回答。 @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
接口在他的Repository
中沒有update
方法,在這種情況下我不能實例化一個Role
,因為這個table
應該被認為是typological
,在應用程序啟動時填充並且永遠不會(可能很少..:) ) 更新。
因此,我必須獲取要添加的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
謝謝你們
問題是您將Roles.users
設置為Users
表中的mappedBy='users'
的擁有實體。 僅保留對擁有實體所做的更改。 相反,請嘗試將mappedBy='roles'
放入Roles
表中。
此外,您當然應該使用Set<Role> role
而不是List
。 列表是有序的,JPA/Spring-Data 將嘗試保留順序,這可能是性能開銷。 此外,使用 JPA 中的Lists
定義的多個 XToMany 關系可能會出現問題。
雖然您可能只想為任何用戶提供一個角色,但 Spring Security 定義並處理ManyToMany
關系。
JPA 有一個更新persist
,既可以保存也可以更新。 此外,對附加實體所做的更改會自動保留(更新)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.