Пользовательский валидатор ограничений не инициализируется при сохранении объекта в спящем режиме в приложении Spring Data - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть приложение Spring (v2.2), в котором я создал специальный валидатор ограничений для поля на одном из объектов, которые мне нравятся,

@Retention(RetentionPolicy.RUNTIME)
public @interface ValidModules {
  String message() default "Only specify approved modules.";
  Class<?>[] groups() default {};
  Class<? extends Payload>[] payload() default {};
}
public class ValidModulesValidator implements ConstraintValidator<ValidModules, List<String>> {

   private final ModuleResourcesConfig moduleResourcesConfig;

   public ValidModulesValidator(ModuleResourcesConfig moduleResourcesConfig) {
      this.moduleResourcesConfig = moduleResourcesConfig;
   }

   public boolean isValid(List<String> inputModules, ConstraintValidatorContext context) {
      ...     
      return true;
   }
}

Когда я использую эту проверку с помощью делая rest api call и имея @Validated сервис, он возвращает ошибки обратно должным образом. Но в тот же вызов, когда я, когда затем сохраняются эти входные данные, он генерирует исключение.

Я использую это, чтобы сохранить modulesRepository.saveAll(modulesInput). Исключение составляет

java.lang.NoSuchMethodException: org.baps.ims.validation.validator.ValidModulesValidator.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_152]
    at java.lang.Class.getConstructor(Class.java:1825) ~[na:1.8.0_152]
    at org.hibernate.validator.internal.util.privilegedactions.NewInstance.run(NewInstance.java:41) ~[hibernate-validator-6.0.17.Final.jar:6.0.17.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorFactoryImpl.run(ConstraintValidatorFactoryImpl.java:43) ~[hibernate-validator-6.0.17.Final.jar:6.0.17.Final]
Flush(DefaultFlushEventListener.java:40) ~[hibernate-core-5.4.4.Final.jar:5.4.4.Final]
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1493)

Я пробовал несколько подходов, прибегая к помощи, но безуспешно. Некоторые вещи, которые я пробовал,

  1. Используйте @Autowired для введения moduleResourcesConfig в пользовательский валидатор вместо того, чтобы иметь конструктор с этим в качестве ввода. Это дало NPE, потому что moduleResourcesConfig никогда не создавался, хотя у меня он был @ Autowired.

  2. Далее я явно указал @Component в валидаторе ограничения, хотя это не должно было иметь было необходимо.

  3. Затем я добавил в приложение бин валидатора, например:

  @Bean
  public Validator validator() {
    return new LocalValidatorFactoryBean();
  }

  @Bean
  public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator());
        return methodValidationPostProcessor;
  }

Я также пытался установить spring.jpa.hibernate.ddl-auto: none.

Также пытался настроить javax.persistence.validation.mode: none.

Ничего из этого не помогло пока что.

Ответы [ 2 ]

0 голосов
/ 20 апреля 2020

Нашел решение , которое сработало для меня.

В основном нужно иметь это,

@Lazy
class SpringValidatorConfiguration {

    @Bean
    @Lazy
    public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(final Validator validator) {
        return new HibernatePropertiesCustomizer() {

            @Override
            public void customize(Map<String, Object> hibernateProperties) {
                hibernateProperties.put("javax.persistence.validation.factory", validator);
            }
        };
    }
}
0 голосов
/ 20 апреля 2020

Я думаю, вам нужно указать ограничение в вашем интерфейсе валидации следующим образом:

@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Constraint(validatedBy = ValidModulesValidator .class)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidModules {
...