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

Spring Boot 2.2.5 does not run bean validation for null fields #20365

Closed
pkubowicz opened this issue Mar 2, 2020 · 3 comments
Closed

Spring Boot 2.2.5 does not run bean validation for null fields #20365

pkubowicz opened this issue Mar 2, 2020 · 3 comments
Labels
for: external-project For an external project and not something we can fix status: duplicate A duplicate of another issue

Comments

@pkubowicz
Copy link

pkubowicz commented Mar 2, 2020

I believe there is a regression between Spring Boot 2.2.4 and 2.2.5 in handling bean validation.

I have a small project reproducing it: https://github.com/pkubowicz/spring-validation-bug

In short:

  • UserDto has @NotBlank field called id, additionally the constructor does a null-check
  • I am running MockMVC tests
  • passing an empty string for id field correctly returns HTTP 400
  • not passing id field causes HTTP 500 while it used to return HTTP 400 (first problem)
  • not passing id causes an exception breaking the MVC test - you cannot write andExpect(status().isBadRequest()) (second problem)

I think apart from fixing validation behaviour, Mock MVC should be fixed so that calling mvc.perform() never throws an exception and you can just write a test asserting on MVC result.

Stacktrace:

Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: JSON conversion problem: Cannot construct instance of `com.example.UserDto`, problem: `java.lang.NullPointerException`; nested exception is com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `com.example.UserDto`, problem: `java.lang.NullPointerException`
 at [Source: (PushbackInputStream); line: 1, column: 15]
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: JSON conversion problem: Cannot construct instance of `com.example.UserDto`, problem: `java.lang.NullPointerException`; nested exception is com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `com.example.UserDto`, problem: `java.lang.NullPointerException`
 at [Source: (PushbackInputStream); line: 1, column: 15]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
	at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
	at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183)
	at com.example.UserControllerTest.returns400ForMissingId(UserControllerTest.java:26)

Curl:

% curl http://localhost:8080/users -H 'Content-Type: application/json' -XPOST --data '{"name": "Joe"}'
{"timestamp":"2020-03-02T10:05:13.085+0000","status":500,"error":"Internal Server Error","message":"JSON conversion problem: Cannot construct instance of `com.example.UserDto`, problem: `java.lang.NullPointerException`; nested exception is com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `com.example.UserDto`, problem: `java.lang.NullPointerException`\n at [Source: (PushbackInputStream); line: 1, column: 15]","path":"/users"}      

% curl http://localhost:8080/users -H 'Content-Type: application/json' -XPOST --data '{"id": "", "name": "Joe"}'
{"timestamp":"2020-03-02T10:05:48.100+0000","status":400,"error":"Bad Request","errors":[{"codes":["NotBlank.userDto.id","NotBlank.id","NotBlank.java.lang.String","NotBlank"],"arguments":[{"codes":["userDto.id","id"],"arguments":null,"defaultMessage":"id","code":"id"}],"defaultMessage":"must not be blank","objectName":"userDto","field":"id","rejectedValue":"","bindingFailure":false,"code":"NotBlank"}],"message":"Validation failed for object='userDto'. Error count: 1","path":"/users"}                                                                                                               
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Mar 2, 2020
@bclozel
Copy link
Member

bclozel commented Mar 2, 2020

@rstoyanchev
Copy link
Contributor

rstoyanchev commented Mar 3, 2020

I believe this issue can be closed as duplicate of spring-projects/spring-framework#24610.

As for having mvc.perform() never throw an exception, that would break existing tests that happen to rely on the current behavior. Also for tests that try to assert the response, that actually run into unhandled errors, would now see response assertion failures (e.g. missing headers) instead of the actual unhandled error. If you really want to do this, you can insert a test Filter and use try-catch before delegating.

@wilkinsona
Copy link
Member

Thanks, @rstoyanchev.

@wilkinsona wilkinsona added for: external-project For an external project and not something we can fix status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project For an external project and not something we can fix status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

5 participants