Я столкнулся с неожиданным поведением при использовании внедрения зависимостей в ConstraintValidator
, который оценивается на уровне класса.
Класс сущности:
@Entity
@ValidDemoEntity
public class DemoEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
Комментарий к валидации:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {DemoEntityValidator.class})
public @interface ValidDemoEntity {
String message() default "{some.demo.validator.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Validator:
public class DemoEntityValidator implements ConstraintValidator<ValidDemoEntity, DemoEntity> {
private DemoEntityRepository demoEntityRepository;
public DemoEntityValidator(DemoEntityRepository demoEntityRepository) {
this.demoEntityRepository = demoEntityRepository;
}
@Override
public void initialize(ValidDemoEntity constraintAnnotation) {
}
@Override
public boolean isValid(DemoEntity demoEntity, ConstraintValidatorContext constraintValidatorContext) {
return true;
}
}
Тестовый класс:
@SpringBootTest
public class ValidatorInstantiationTest {
private Validator validator;
@Before
public void setUp() throws Exception {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
validator = validatorFactory.getValidator();
}
@Test
public void shouldInitiateAndCallDemoEntityValidator() {
DemoEntity demoEntity = new DemoEntity();
validator.validate(demoEntity);
}
}
Проверка сущности приводит к:
javax.validation.ValidationException: HV000064: Unable to instantiate ConstraintValidator: com.example.demo.DemoEntityValidator.
и далее по трассе стека:
Caused by: java.lang.NoSuchMethodException: com.example.demo.DemoEntityValidator.<init>()
, который указывает, что Hibernate
пытался инициировать класс, вместо того чтобы позволить Spring позаботиться об этом.
Странно то, что внедрение зависимостей отлично работает для проверок, применяемых на уровне полей.
Код доступен на GitHub .