Я пытаюсь вручную проверить граф объектов. У меня не было проблем с этим при использовании Hibernate SessionFactory. Поскольку я перешел на Hibernate JPA, вложенные сущности больше не проверяются. Почему?
- Проверка на основе событий Hibernate выполняется с группой по умолчанию и работает на этапах pre-persiste / pre-update / pre-remove, но проверка вручную неНе удается обнаружить ошибку проверки во вложенных объектах.
- Весь граф объектов загружен с нетерпением, поэтому я предполагаю, что TraversableResolver не является проблемой здесь. Во всяком случае, я все еще объявил пользовательский TraversableResolver, который всегда запрашивает переход к вложенным объектам.
- Если я создаю новый граф сущностей в модульном тесте вне контекста постоянства, обнаруживается ошибка проверки. Тем не менее, если я отсоединяю родительскую сущность от контекста персистентности, ошибка проверки все еще не найдена.
Буду признателен за любую помощь в понимании этой проблемы.
Я использую org.springframework.boot:spring-boot-starter-data-jpa
(Spring Boot 2.1.7.RELEASE), в комплекте с Hibernate 5.3. 10.Final . Я также использую Lombok.
Вот мой код. Если в родительском классе присутствует поле alwaysAnError
, будет обнаружена ошибка проверки. Если это поле вложено в дочерний элемент @Valid, ошибка не найдена.
Parent.java
@Data @Builder @NoArgsConstructor @AllArgsConstructor
@Entity
@Table(name = "parent")
public class Parent {
[...]
@Valid
@Builder.Default
@OneToMany(mappedBy = "file", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@Fetch(value = FetchMode.SUBSELECT)
private List<@Valid Child> children = new ArrayList<>();
}
Child.java
@Data @Builder @NoArgsConstructor @AllArgsConstructor
@Entity
@Table(name = "child")
public class Child {
[...]
@ManyToOne
@JoinColumn(name = "file_id")
private File file;
@NotNull
@Transient
private String alwaysAnError = null;
}
ValidationService.java
Validator validator = Validation.byDefaultProvider()
.configure()
.traversableResolver(new TraversableResolver() {
@Override
public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType, Path pathToTraversableObject, ElementType elementType) {
return true;
}
@Override
public boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType, Path pathToTraversableObject, ElementType elementType) {
return true;
}
})
.buildValidatorFactory()
.getValidator();
Set<ConstraintViolation<Declaration>> constraintViolations = validator.validate(fileInstance, Default.class);
if (!constraintViolations.isEmpty()) {
throw new RuntimeException(constraintViolations);
}
Смежные вопросы: