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

An exception is thrown when validation fails on public nested fields [SPR-13107] #17698

Closed
spring-issuemaster opened this issue Jun 9, 2015 · 4 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Jun 9, 2015

Tapio Koskinen opened SPR-13107 and commented

Binding and validation work fine for nested fields even without getters and setters, but an exception is thrown when validation constraints are not met for nested fields. In this case when nested.number is greater than 5.

public class JavaBean {
    @Valid
    public NestedJavaBean nested;
    @Max(5)
    public Integer number;
}

public class NestedJavaBean {
    @NotNull
    @Max(5)
    public Integer number;
}
java.lang.IllegalStateException: JSR-303 validated property 'nested.number' does not have a corresponding accessor for Spring data binding - check your DataBinder's configuration (bean property versus direct field access)
        at org.springframework.validation.beanvalidation.SpringValidatorAdapter.processConstraintViolations(SpringValidatorAdapter.java:158)
        at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:107)
        at org.springframework.validation.DataBinder.validate(DataBinder.java:781)
        at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.validateIfApplicable(AbstractMessageConverterMethodArgumentResolver.java:188)
        at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:104)
        at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
....
Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'nested' of bean class [org.springframework.samples.mvc.messageconverters.JavaBean]: Bean property 'nested' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
        at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:731)
        at org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:572)
        at org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:549)
        at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:720)
        at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
        at org.springframework.validation.AbstractBindingResult.getRawFieldValue(AbstractBindingResult.java:283)
        at org.springframework.validation.beanvalidation.SpringValidatorAdapter.processConstraintViolations(SpringValidatorAdapter.java:143)

Affects: 4.1.6

Attachments:

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 9, 2015

Stéphane Nicoll commented

Looking at your stracktrace you are using the properties binding (i.e. with getter/setter) and not the field binding (the fact that the field is public does not matter at all). You need to configure field binding if that's what you want to use.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 9, 2015

Tapio Koskinen commented

Thank you, it solved my problem. (Link for future reference: http://docs.spring.io/spring-framework/docs/4.1.x/javadoc-api/org/springframework/validation/DataBinder.html#initDirectFieldAccess--)

However, if "nested" was a list, an exception would still be thrown (JSON would be something like {"nested": [{"number": 6}]}):

java.lang.IllegalStateException: JSR-303 validated property 'nested[0].number' does not have a corresponding accessor for Spring data binding - check your DataBinder's configuration (bean property versus direct field access)
	at org.springframework.validation.beanvalidation.SpringValidatorAdapter.processConstraintViolations(SpringValidatorAdapter.java:158)
	at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:107)
	at org.springframework.validation.DataBinder.validate(DataBinder.java:781)
	at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.validateIfApplicable(AbstractMessageConverterMethodArgumentResolver.java:188)
	at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:104)
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
....
Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'nested[0].number' of bean class [org.springframework.samples.mvc.messageconverters.JavaBean]: Field 'nested[0].number' does not exist
	at org.springframework.beans.DirectFieldAccessor.getPropertyValue(DirectFieldAccessor.java:116)
	at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
	at org.springframework.validation.AbstractBindingResult.getRawFieldValue(AbstractBindingResult.java:283)
	at org.springframework.validation.beanvalidation.SpringValidatorAdapter.processConstraintViolations(SpringValidatorAdapter.java:143)
	... 44 more

Is this a bug?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 9, 2015

Stéphane Nicoll commented

Nested field binding is supported as from Spring 4.2 only, we never supported that use case before. I am still not sure what you're reporting here exactly. Your fields that worked fine probably have getters/setters (so it wasn't using the field at all).

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jun 9, 2015

Tapio Koskinen commented

4.2.0.RC1 fixed the issue, great!

I wanted to use DTOs without setters/getters (only public fields) with Spring MVC, and also to perform request validation with them. It worked fine except when there were validation errors in nested classes. There's no special reason to not use getters/setters, just that I find them unnecessary and redundant in DTOs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.