簡體   English   中英

JPA ManyToMany更新記錄

[英]JPA ManyToMany updating record

我有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;
}

Role是一個簡單的enum ,如下所示:

public enum Role {
   ROLE_ADMIN,
   ROLE_USER;
}

現在讓SpringBoot創建空database並假設添加一些默認記錄:

在此處輸入圖像描述

現在考慮Roles表將包含最多 2 個角色: ROLE_ADMINROLE_USER 我設法使用Roles添加新User ,我設法刪除具有相應RoleUser (檢索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 RolesUser

我想將此UserRolesROLE_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM