Ghaiath
Ghaiath

Reputation: 53

How to get only one role from a set of roles

I'm trying to implement a simple spring security project where basically I have user and role entities. I have a set of roles "ADMIN" and "USER".

Now I want to assign only "USER" role along with creating a new user.

I have tried to use List and collections with the same problem.

The User entity has 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;}

And Role entity:

public class Role {

    }
    @Id
    private int role_id;
    private String role;

}

And here is the saveMyUser method to save the user to my database. When I use:

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())); assign all roles to the user, since I want for new user only assign the "USER" role.

I tried user.setRoles(new HashSet<>(roleRepository.findByRole(2))); and also I tried user.setRoles(new HashSet<>(roleRepository.findByID(2))); with this error: Cannot infer type arguments for HashSet<>.

Role table in my database:

role_id    role
1          ADMIN
2          USER

Upvotes: 0

Views: 2324

Answers (3)

gautam basak
gautam basak

Reputation: 1

Controller code:

@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";
} 

Role Repository code:

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

Its working absolutely fine for me as i also had the same problem.

Upvotes: 0

Player One
Player One

Reputation: 617

If you're using a Spring Data repository then one issue is that the query names/parameter types you've chosen don't match your entity. There's no field called "ID", and the type of role is String, not int.

Your best option would be to make your repository method signature

Role findByRole(String roleName);

You should also change the name and data type of the ID in your Role object - by convention Java uses camelCase, not snake_case, and while an int is probably fine for a table like ROLE that's likely to stay small, in a general case you'll want the larger keyspace that long gives you. It's also nicer to have a consistent datatype for your ids across your objects - it saves you from having to think "wait, was this one an int or a long?". It should be private long roleId;.

Upvotes: 0

Matt
Matt

Reputation: 2213

The HashSet constructor takes a Collection, not a single element. This line:

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

creates a new HashSet with all of your roles. This line

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

tries to create a new HashSet with a single element in the constructor, which won't work as a Role is not an instance of Collection.

Just fetch your role, create a HashSet, add the role and THEN set the user's role:

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

Upvotes: 1

Related Questions