Обычно у нас есть клиент-серверное приложение, использующее Spring Boot 2.0.2 (содержащее Spring Data и Spring Security) на сервере.
У нас есть пользовательский объект со следующей реализацией:
@Entity
@Table(name="USERS")
public class User implements Serializable {
@Id
@Column(name="ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name="USERNAME", unique = true)
private String username;
@Column(name="PASSWORD")
private String password;
@ManyToMany(fetch = FetchType.LAZY)
@Cascade(CascadeType.SAVE_UPDATE)
@JoinTable
(
name="USER_INITSTATES",
joinColumns={ @JoinColumn(name="USER_ID", referencedColumnName="ID") },
inverseJoinColumns={ @JoinColumn(name="INITSTATE_ID", referencedColumnName="ID") }
)
private List<InitState> initStates = new ArrayList<>();
public List<InitState> getInitStates() {
return initStates;
}
}
И у нас есть следующая реализация для получения InitState
(своего рода объект конфигурации для клиента) текущего пользователя, вошедшего в систему:
@PostFilter("false")
public List<InitState> loadActiveUserInitStates() {
if (SecurityContextHolder.getContext().getAuthentication() != null) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();
User user = userService.findByUsername(currentPrincipalName);
return user.getInitStates();
}
return null;
}
Проблемная часть, где мы возвращаем user.getInitStates()
. Поскольку переменная User.initStates
настроена на FetchType.LAZY
, список возвращается как пакет сохраняемости hibernate / jpa. Теперь, когда Spring Security оценивает список после извлечения с помощью @PostFilter
-аннотации, он просматривает список и отфильтровывает объекты, к которым нет доступа (конечно, у нас есть более сложное выражение, которое false
, но в качестве примера, это будет сделать). Когда отфильтрованный список возвращается вызывающей стороне, hibernate хочет сохранить список и удаляет все ссылки InitStates
из объекта User
.
Мои два вопроса:
* Почему Hibernate сохраняет список без какого-либо явного вызова? Есть ли документация такого поведения?
* (Как) я могу настроить / отключить это поведение?