jirutka / validator-collection

The easiest way to validate collections of basic types using Bean Validation.
116 stars 31 forks source link

Issue when more than 1 validator factory are present in classpath #19

Open thekalinga opened 8 years ago

thekalinga commented 8 years ago

In my project, I have an additional validator factory for Method validation along with the validator auto registered by spring boot (with name mvcValidator) in classpath

  @Bean
  public LocalValidatorFactoryBean validatorFactory(MessageSource messageSource) {
    LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
    factoryBean.setValidationMessageSource(messageSource);
    return factoryBean;
  }

  @Bean
  public MethodValidationPostProcessor methodValidationPostProcessor(
      LocalValidatorFactoryBean validatorFactory) {
    MethodValidationPostProcessor validationPostProcessor = new MethodValidationPostProcessor();
    validationPostProcessor.setValidator(validatorFactory);
    return validationPostProcessor;
  }

When I try to validate a collection, I get the following exception

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cz.jirutka.validator.collection.CommonEachValidator': Unsatisfied dependency expressed through field 'factory': No qualifying bean of type [javax.validation.ValidatorFactory] is defined: expected single matching bean but found 2: mvcValidator,validatorFactory; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.validation.ValidatorFactory] is defined: expected single matching bean but found 2: mvcValidator,validatorFactory

Is there a way to configure hibernate and spring to use mvcValidator with CommonEachValidator when more than one validators exist in classpath?

chrischennx commented 8 years ago

Have you found a solution?

thekalinga commented 8 years ago

No..

Mati20041 commented 7 years ago

+1

Dr4K4n commented 7 years ago

I had the same issue. Fixed it by providing my own ValidatorFactory and marking it @Primary. I'm not sure if this is a very good solution, as I don't know if just overwrote some sensible defaults normally provided by spring boot.

@Bean
@Primary
public ValidatorFactory getValidatorFactory() {
    return new LocalValidatorFactoryBean();
}
cr-orilibhaber commented 4 years ago

The issue I had was a collision between "defaultValidator" and "mvcValidator". After spending some time with it, I "solved" it by providing two bean definitions of my own, overriding those predefined beans:

@Bean("defaultValidator") @Scope("prototype") public Validator getDefaultBeanValidator(){ return Validation.buildDefaultValidatorFactory().getValidator(); }

@Bean("mvcValidator") @Scope("prototype") public Validator getMvcBeanValidator(){ return Validation.buildDefaultValidatorFactory().getValidator(); }

Of course, Spring complained that those beans are already defined, so I also enabled overriding via applicaiton.properties: spring.main.allow-bean-definition-overriding=true

And that did the trick for me. I must say, I didn't enjoy hacking into it, I would much prefer a more clean solution.