Spring Boot JPA-什么是将角色分配给用户的适当方法?

发布于 2025-01-21 19:32:46 字数 2898 浏览 0 评论 0原文

我正在尝试开发一个应用程序,在该应用程序中,用户可以分配特定角色,并基于该角色,他们可以访问某些功能。这就是我到目前为止所拥有的:

用户类:

@Entity
@Table(name = "users",
    uniqueConstraints = {
      @UniqueConstraint(columnNames = "username"),
      @UniqueConstraint(columnNames = "email")
    })
public class User {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "usid_generator")
  @SequenceGenerator(name = "usid_generator", initialValue = 1000, allocationSize = 1, sequenceName = "usid_seq")
  private Long id;

  @NotBlank
  @Size(max = 20)
  private String username;

  @NotBlank
  @Size(max = 50)
  @Email
  private String email;

  @NotBlank
  @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
  @Size(max = 120)
  private String password;

  @OneToMany(cascade = CascadeType.ALL,
      fetch = FetchType.LAZY)
  @JoinTable(name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id"))
  private Set<Role> roles = new HashSet<>();

  private Integer notifications;

角色类:

@Entity
@Table(name = "roles")
public class Role {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "roleid_generator")
  @SequenceGenerator(name = "roleid_generator", initialValue = 100, allocationSize = 1, sequenceName = "roleid_seq")
  private Integer id;

  @Enumerated(EnumType.STRING)
  @Column(length = 20)
  private ERole name;

但是,我正在涉足某些问题。我在应用程序的前端有一些按钮,可以更改用户的角色,这是一个示例:

@PutMapping("/users/setadmin/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<User> setAdmin(@PathVariable("id") Long id, @RequestBody User user) {
        Optional<User> userData = userRepository.findById(id);
        Optional<Role> adminRole = roleRepository.findByName(ERole.ROLE_ADMIN);
        Set<Role> roles = new HashSet<>();
        roles.add(adminRole.get());
        if (userData.isPresent()) {
            User _user = userData.get();
            _user.setRoles(roles);
            return new ResponseEntity<>(userRepository.save(_user), HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

艾普尔存储在单独的类中:

public enum ERole {
  ROLE_USER,
  ROLE_MODERATOR,
  ROLE_ADMIN
}

但是,通过使用这种方法,我会遇到两个错误:

  1. 我整个数据库中似乎无法拥有三个以上的用户。每次我创建一个新用户,都有另一个用户已经有错误的角色。这是我试图将角色用户分配给新帐户的示例,因为已经在DB中拥有另一个用户,

Java.sql.sqlintegrityconstrityconstraintviolation exception:重复输入'1'for键'user_roles.uk_5q4rc4rc4fh1on6567qk69uesvyf'

  1. 当我从db中删除用户时,他们分配的角色将从角色表中删除。因此,如果我删除具有角色主持人的用户,则角色主持人本身也会删除。

我猜这是用户类上cascadeType.all属性的问题。我正在阅读一些有关级联反应类型的文档,但我无法弄清楚我应该使用哪个文档,或者根本不知道这是问题所在。任何帮助都非常感谢

I'm trying to develop an application in which users get assigned a specific role, and based on that role they have access to certain functionalities. This is what I have so far:

User class:

@Entity
@Table(name = "users",
    uniqueConstraints = {
      @UniqueConstraint(columnNames = "username"),
      @UniqueConstraint(columnNames = "email")
    })
public class User {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "usid_generator")
  @SequenceGenerator(name = "usid_generator", initialValue = 1000, allocationSize = 1, sequenceName = "usid_seq")
  private Long id;

  @NotBlank
  @Size(max = 20)
  private String username;

  @NotBlank
  @Size(max = 50)
  @Email
  private String email;

  @NotBlank
  @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
  @Size(max = 120)
  private String password;

  @OneToMany(cascade = CascadeType.ALL,
      fetch = FetchType.LAZY)
  @JoinTable(name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id"))
  private Set<Role> roles = new HashSet<>();

  private Integer notifications;

Role class:

@Entity
@Table(name = "roles")
public class Role {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "roleid_generator")
  @SequenceGenerator(name = "roleid_generator", initialValue = 100, allocationSize = 1, sequenceName = "roleid_seq")
  private Integer id;

  @Enumerated(EnumType.STRING)
  @Column(length = 20)
  private ERole name;

However, I'm runnning into some issues. I have some buttons on the front end of my application that allow me to change the role of a user, here is one example:

@PutMapping("/users/setadmin/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<User> setAdmin(@PathVariable("id") Long id, @RequestBody User user) {
        Optional<User> userData = userRepository.findById(id);
        Optional<Role> adminRole = roleRepository.findByName(ERole.ROLE_ADMIN);
        Set<Role> roles = new HashSet<>();
        roles.add(adminRole.get());
        if (userData.isPresent()) {
            User _user = userData.get();
            _user.setRoles(roles);
            return new ResponseEntity<>(userRepository.save(_user), HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

The ERoles are stored in a separate class:

public enum ERole {
  ROLE_USER,
  ROLE_MODERATOR,
  ROLE_ADMIN
}

However, by using this approach I'm getting two errors:

  1. I can't seem to have more than three users in the whole database. Every time I create a new user with a role that another user already has I get an error. Here is an example of what I got when trying to assign the role USER to a new account, after already having another user with that role in the DB:

java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'user_roles.UK_5q4rc4fh1on6567qk69uesvyf'

  1. When I delete a user from the DB, the role that they had assigned gets deleted from the roles table. So, if I delete a user who had the role MODERATOR, the role MODERATOR itself gets deleted as well.

I'm guessing it's an issue with the CascadeType.ALL property on the User class. I was reading some documentation about the types of cascades, but I can't figure out which one I should use, or if that's the problem at all. Any help is much appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你另情深 2025-01-28 19:32:46

@Onetomany注释表明一个用户可以具有多个角色,但是一个角色与多个用户无关。

尝试一下:

User:
@ManyToMany(cascade = CascadeType.ALL)
    private Set<Role> roles = new HashSet<>();

Role:
@ManyToMany(mappedBy = "roles")
private Set<User> users;

@OneToMany annotation indicates that one user can have multiple roles, but one role cannot relate to multiple users.

Try with this:

User:
@ManyToMany(cascade = CascadeType.ALL)
    private Set<Role> roles = new HashSet<>();

Role:
@ManyToMany(mappedBy = "roles")
private Set<User> users;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文