У меня есть страница входа, где данные будут извлечены из базы данных
Пользователь
@Setter
@Getter
@Entity
@Table(name = "USER_DETAILS")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "USER_ID")
private Long id;
@Column(name = "USER_NAME")
private String userName;
@Column(name = "USER_PASSWORD")
private String userPassword;
@Transient
private Set<Role> roles;
@ManyToMany
@JoinTable(name = "USER_ROLE", joinColumns = @JoinColumn(name = "USER_ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
Роль
@Setter
@Getter
@Entity
@Table(name = "USER_ROLE")
public class Role implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ROLE_ID")
private Long id;
@Column(name = "USER_NAME")
private String userName;
@Column(name = "ROLE_NAME")
private String roles;
@Transient
private Set<User>users;
@ManyToMany(mappedBy = "roles")
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
UserDetailServiceImpl
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
System.out.println("Name "+user.getUserName());
System.out.println("role is "+user.getRoles());
if (null == user) {
throw new UsernameNotFoundException("No user present with username: " + username);
}
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Role role : user.getRoles()){
grantedAuthorities.add(new SimpleGrantedAuthority(role.getUserName()));
}
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getUserPassword(), grantedAuthorities);
}
}
Таблица
Роль
ROLE_ID | USER_NAME | ROLE_NAME
1 John Admin
Пользователь
USER_ID | USER_NAME | USER_PASSWORD | USER_ROLE
1 John pass Admin
Выход
Name John role is null 2018-03-12 00:52:06.362 ERROR 12563 --- [nio-8088-exec-8] w.a.UsernamePasswordAuthenticationFilter : An internal error occurred while trying to authenticate the user.
org.springframework.security.authentication.InternalAuthenticationServiceException: null
Я не могу понять значение роли. Что не так со структурой базы данных?




Для работы @ManyToMany вам нужно 3 таблицы, а не 2. Две родительские таблицы обычно связаны через третью таблицу, содержащую два внешних ключа. Итак, здесь должна быть третья таблица с role_id и user_id.
Кроме того, вместо добавления аннотации @ManyToMany к геттерам попробуйте добавить ее во время самого объявления. Примерно так в классе User,
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "user_role",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles = new HashSet<>();
И такая же модификация в классе Role:
@ManyToMany(mappedBy = "roles")
private Set<User> users = new HashSet<>();
Здесь user_role - третья таблица.