Я использую аннотацию @AuthenticationPrincipal на уровне контроллера как таковую
@PutMapping(value = "add-book", consumes = "application/json")
public GenericResponse addBook(@AuthenticationPrincipal User user, @RequestBody Book book) {
return userService.addBook(user, book);
}
и отправляю пользователя на сервисный уровень. Но, как видно из приведенной ниже модели пользователя, есть атрибут отложенной выборки, называемый bookList.
@Entity
@JsonIgnoreProperties(value = {"createdAt", "updatedAt", "roles", "enabled",
"authorities", "credentialsNonExpired", "accountNonLocked", "accountNonExpired"})
@Data
@Accessors(chain = true)
public class User extends Base implements UserDetails, Serializable {
@Column(unique = true)
@Size(min = 4, max = 20)
@NotNull
private String username;
@NotNull
private String password;
@Column(unique = true)
@NotNull
@Email
private String email;
@ElementCollection(fetch = FetchType.EAGER)
private List<Role> roles = new ArrayList<>();
@JsonBackReference
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
@JoinColumn(name = "book_id")
private List<Book> bookList = new ArrayList<>();
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles.stream().map(r -> new
SimpleGrantedAuthority(r.toString())).collect(Collectors.toList());
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Так что в этом случае пользователь, предоставленный аннотацией @AuthenticationPrincipal, не содержит атрибут books, поскольку он извлекается с отложенной выборкой. Итак, мне пришлось сделать следующее в сервисе:
public GenericResponse addBook(User user, Book book) {
User userFetched = loadUserByUsername(user.getUsername());
List<Book> bookList = userFetched.getBookList();
bookList.add(book);
if (userRepository.save(userFetched) != null) {
return genericResponseService.createResponseNoError(userFetched);
} else throw new RuntimeException();
}
Несмотря на то, что у меня есть пользователь, я использую loadByUsername, чтобы избежать исключения отложенной инициализации. Это хорошая практика или у меня есть лучший способ получить bookList пользователя?