如何从一组角色中仅获得一个角色

时间:2019-04-14 22:46:06

标签: java spring-boot

我正在尝试实现一个简单的spring安全项目,该项目基本上具有用户和角色实体。我有一组角色“ ADMIN”和“ USER”。

现在,我只希望分配“ USER”角色以及创建新用户。

我尝试过使用List和collections遇到同样的问题。

用户实体具有Set<Role>

public class User {

    @Id
    @Column(name = "user_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int user_id;

    @NotNull
    @Column(name = "user_name", unique = true)
    private String userName;

    @NotNull
    @Column(name = "first_name")
    private String firstName;

    @NotNull
    @Column(name = "last_name")
    private String lastName;

    @Column(name = "roles")
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;}

和角色实体:

public class Role {

    }
    @Id
    private int role_id;
    private String role;

}

这是将用户保存到我的数据库的saveMyUser方法。 当我使用时:

public void saveMyUser(User user) {
    Set<Role> hash_Set = new HashSet<Role>();
    user.setPassword(encoder().encode(user.getPassword()));
        user.setRoles(new HashSet<>(roleRepository.findAll())); <--- Here
        userRepository.save(user);
    }

user.setRoles(new HashSet<>(roleRepository.findAll()));将所有角色分配给用户,因为我要为新用户仅分配“ USER”角色。

我尝试了user.setRoles(new HashSet<>(roleRepository.findByRole(2)));,也尝试了user.setRoles(new HashSet<>(roleRepository.findByID(2)));,但出现了以下错误:无法推断HashSet <>的类型参数。

我数据库中的角色表:

role_id    role
1          ADMIN
2          USER

3 个答案:

答案 0 :(得分:1)

HashSet构造函数采用Collection,而不是单个元素。这行:

user.setRoles(new HashSet<>(roleRepository.findAll()));

使用您的所有角色创建一个新的HashSet。这行

user.setRoles(new HashSet<>(roleRepository.findByRole(2)));

尝试使用构造函数中的单个元素创建一个新的HashSet,由于Role不是Collection的实例,因此无法正常工作。

只需获取您的角色,创建一个HashSet,添加该角色,然后设置用户的角色,即可:

Role role = roleRepository.findByRole(2);
Set<Role> roles = new HashSet<>();
roles.add(role);
user.setRoles(roles);

答案 1 :(得分:0)

如果您使用的是Spring Data存储库,那么一个问题是您选择的查询名称/参数类型与您的实体不匹配。没有名为“ ID”的字段,role的类型为String,而不是int

您最好的选择是使存储库方法签名

Role findByRole(String roleName);

您还应该更改Role对象中ID的名称和数据类型-按照惯例,Java使用camelCase,而不是snake_case,并且int对于像ROLE这样的表可能很小的表可能很好,通常情况下,您会希望使用long为您提供的更大的键空间。为对象之间的ID设置一致的数据类型也更好-它使您不必考虑“等一下,这是int还是long?”。应该是private long roleId;

答案 2 :(得分:0)

控制器代码:

@PostMapping("/do_register")
public String registration(@ModelAttribute("user") User user, Model model) 
{       
    user.setRoles(new HashSet<>(roleRepository.findByName("USER")));
    user.setEnabled(true);
    user.setPassword(passwordEncoder.encode(user.getPassword()));
    userRepository.save(user);
    return "signup";
} 

角色存储库代码:

public interface RoleRepository extends JpaRepository<Role, Integer>
{
    public Set<Role> findByName(String USER);
} 

它对我来说非常好,因为我也遇到了同样的问题。