Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSR validator bean missing if a custom Spring Validator bean is present #8976

Closed
oyvindhorneland opened this issue Apr 24, 2017 · 9 comments
Closed
Assignees
Labels
type: regression A regression from a previous release
Milestone

Comments

@oyvindhorneland
Copy link

oyvindhorneland commented Apr 24, 2017

This problem occurred after upgrade from Spring Boot 1.5.2 to 1.5.3.

I have some custom Spring validator beans for Spring Data REST while also relying on standard JSR validator in other parts of the application.

After upgrading from Spring Boot 1.5.2 to 1.5.3 there is no longer a JSR validator bean present.

Error:

Bean method 'defaultValidator' in 'DefaultValidatorConfiguration' not loaded because @ConditionalOnMissingBean (types: javax.validation.Validator,org.springframework.validation.Validator; SearchStrategy: all) found beans 'beforeSaveUserValidator', 'beforeCreateGroupValidator', 'beforeCreateUserValidator'

Debug auto configuration:

DefaultValidatorConfiguration#defaultValidator:
      Did not match:
         - @ConditionalOnMissingBean (types: javax.validation.Validator,org.springframework.validation.Validator; SearchStrategy: all) found beans 'beforeSaveUserValidator', 'beforeCreateGroupValidator', 'beforeCreateUserValidator' (OnBeanCondition)

c9561f0 changed this behaviour since it does not provide a validator if a Spring validator is present.

Not sure if this is should be considered a bug and I can easily work around this problem and provide this bean myself, but perhaps Spring Boot could create a JSR validator if not present?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 24, 2017
@oyvindhorneland
Copy link
Author

Also the Spring validators for Spring Data REST only supports a specific class. Perhaps Spring Boot autoconfiguration should check if a LocalValidatorFactoryBean bean is present and create if missing?

@philwebb
Copy link
Member

Thanks for the report. We missed the user-case where a Spring Validator is present but it doesn't implement JSR 303 validation.

Can you share the your validator bean definitions? I'm curious which classes you used.

Also the Spring validators for Spring Data REST only supports a specific class. Perhaps Spring Boot autoconfiguration should check if a LocalValidatorFactoryBean bean is present and create if missing?

Can you point me at the part of Spring Data that does this?

@philwebb philwebb added the status: waiting-for-feedback We need additional information before we can continue label Apr 24, 2017
@oyvindhorneland
Copy link
Author

An example validator bean looks like this: https://gist.github.com/oyvindhorneland/c16d727e96ab7facb195fd3ab39a5c7b

The bean definition must be manually provided, as documented in http://docs.spring.io/spring-data/rest/docs/2.6.3.RELEASE/reference/html/#validation. They are invoked from https://github.com/spring-projects/spring-data-rest/blob/master/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/event/ValidatingRepositoryEventListener.java.

Official samples for registering these validators seem to be lacking and spring-projects/spring-data-examples#150 requests such a sample, however I found the guide in http://www.baeldung.com/spring-data-rest-validators helpful.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Apr 24, 2017
@snicoll snicoll added priority: high type: regression A regression from a previous release and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Apr 25, 2017
@snicoll snicoll added this to the 1.5.4 milestone Apr 25, 2017
@snicoll snicoll self-assigned this Apr 25, 2017
snicoll added a commit to snicoll/spring-boot that referenced this issue Apr 26, 2017
This commit restores and adds tests that validates
`ValidationAutoConfiguration` will configure a JSR validator even if a
Spring Validator is present.

Closes spring-projectsgh-8976
@oyvindhorneland
Copy link
Author

Superb! Thank you!

@snicoll
Copy link
Member

snicoll commented Apr 28, 2017

@oyvindhorneland a new 1.5.4.BUILD-SNAPSHOT with the fix is available. Would you be so kind to test it on your project please?

If you need instructions to add the necessary snapshot repo, you can create an empty app from start.spring.io. Thanks!

@oyvindhorneland
Copy link
Author

oyvindhorneland commented Apr 28, 2017

@snicoll 1.5.4.BUILD-SNAPSHOT works well and fixes this issue. One less bean to manage 👍

mbhave pushed a commit to mbhave/spring-boot that referenced this issue May 2, 2017
This commit ensures that a primary JSR 303 and Spring Validator will be
exposed if the auto-configuration kicks in. As `LocalValidatorFactoryBean`
exposes 3 contracts (JSR-303 `Validator` and `ValidatorFactory` as well as
the `Spring` validator one), this makes sure that those types can be
injected by type.

`LocalValidatorFactoryBean` exposes 3 contracts and we're only checking
for the absence of a `javax.validation.Validator` to auto-configure a
`LocalValidatorFactoryBean`. If no standard JSR validator exists but a
Spring's `Validator` exists and is primary, we shouldn't flag the
auto-configured one as `@Primary`. Previous iterations on this feature
have made sure that we'll auto-configure at most one
`javax.validation.Validator` so not flagging it `@Primary` is no problem.

This commit also restores and adds tests that validates
`ValidationAutoConfiguration` will configure a JSR validator even if a
Spring Validator is present.

This effectively fixes spring-projectsgh-8495 in a different way.

Closes spring-projectsgh-8979
Closes spring-projectsgh-8976
@asaarnak
Copy link

asaarnak commented Jun 12, 2017

After update from 1.5.3 to 1.5.4 and an autoconfig error appears.
Using @qualifier("beanValidatorFactory") fixes this, but is it expected?

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.validation.Validator' available: more than one 'primary' bean found among candidates: [beanValidatorFactory, defaultValidator]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.determinePrimaryCandidate(DefaultListableBeanFactory.java:1372)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.determineAutowireCandidate(DefaultListableBeanFactory.java:1333)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1113)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
	... 66 more

@snicoll
Copy link
Member

snicoll commented Jun 12, 2017

@asaarnak this issue is closed. If you believe you've found an issue, please create a separate issue with a sample that reproduces the problem. Thanks!

@asaarnak
Copy link

asaarnak commented Aug 8, 2017

@snicoll Finally i had time to take a look at this issue and managed to workaround it.
We were returning javax.validation.ValidationFactory as bean type so the following condition created new bean defaultValidator.

@ConditionalOnMissingBean(type = { "javax.validation.Validator", "org.springframework.validation.Validator" })

The fix was to return the LocalValidatorFactoryBean type instead of ValidatorFactory.
@Bean public LocalValidatorFactoryBean beanValidatorFactory()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A regression from a previous release
Projects
None yet
Development

No branches or pull requests

5 participants