Reputation: 53
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
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
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
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