The Spring validation @NotNull does not validate
Solution 1
I think I found the answer thanks to this post:
jsr-303-valid-annotation-nested-object-not-working
So as soon as I added the @Valid to these fields:
@Valid
private List<Mapping> mappings;
And these fields inside Mapping:
@JsonProperty(value="account_id")
@Valid
@NotNull
private String accountId;
@JsonProperty(value="last_updated_at")
@Valid
@NotNull
private OffsetDateTime lastUpdatedAt;
The validation started working.
Also I removed the @NotNull
in the setter()
methods:
Setters() like this:
@Override
public void setAccountId (String accountId) {
this.accountId = accountId;
}
@Override
public void setLastUpdatedAt(OffsetDateTime lastUpdatedAt) {
this.lastUpdatedAt = lastUpdatedAt;
}
Also my code worked without any of the Validator beans which I added to Main().
Solution 2
In my case, I was missing the validation dependency. From baeldung;
Starting with Boot 2.3, we also need to explicitly add the spring-boot-starter-validation dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
blueSky
Updated on June 14, 2022Comments
-
blueSky almost 2 years
I’m trying to validate a POST request using Spring Validator. This is the Object I’m trying to validate:
@Validated public class Request implements Serializable { private static final long serialVersionUID = 1L; private Long id1; private Long id2; private String s; private List<Mapping> mappings; public Request() {} public Request (Long id1, Long id2, String s, List<Mapping> mappings) { this.id1 = id1; this.id2 = id2; this.s = s; this.mappings = mappings; } //getter() and setter() methods. }
And this is the Mapping class:
@Validated public class Mapping implements Serializable { private static final long serialVersionUID = 1L; @JsonProperty(value="id") private Long id; @JsonProperty(value="string") private String string; @JsonProperty(value="account_id") @NotNull private String accountId; @JsonProperty(value="last_updated_at") @NotNull private OffsetDateTime lastUpdatedAt; // Getter and setters() // I'll skip the getter() and setter() for id and string fields. @Override public String getAccountId() { return accountId; } @Override public void setAccountId (@NotNull String accountId) { this.accountId = accountId; } @Override public OffsetDateTime getLastUpdatedAt() { return lastUpdatedAt; } @Override public void setLastUpdatedAt(@NotNull OffsetDateTime lastUpdatedAt) { this.lastUpdatedAt = lastUpdatedAt; } }
This is the message being posted:
[Request [id1=null, id2=null, s=6eq2J6, mappings= [Mapping [id=2779, string=6eq2J6, accountId=null, lastUpdatedAt=null]]]]
This is how I receive the request, but the bindingResult.hasErrors() is always empty. The pushRequest is exactly as it was sent.
@RestController @RequestMapping(value="/${path}", method={RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT}) @Validated public class MappingController { @PostMapping(value="/", consumes={"application/json"}) public void processMappings (@Valid @RequestBody Optional<Request> pushRequest, BindingResult bindingResult) { if (bindingResult.hasErrors()) { log.info("Error!"); } } }
Why the
@NotNull
for accountId and lastUpdatedAt does not make the validation to fail when they haveNull
value?I've tried to find the solution by searching this error, the solutions was to add
@Validated
to theRequest, Mapping and MappingController
classes, which did not solve the problem.Another solution was to add these
Beans
to theMain()
class, which did not solve the problem.public class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); //System.out.println("version: " + SpringVersion.getVersion()); // version: 5.1.0.RC1 } @Bean public javax.validation.Validator localValidatorFactoryBean() { return new LocalValidatorFactoryBean(); } @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor mvProcessor = new MethodValidationPostProcessor(); mvProcessor.setValidator(validator()); return mvProcessor; } @Bean public LocalValidatorFactoryBean validator() { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setProviderClass(HibernateValidator.class); validator.afterPropertiesSet(); return validator; } }
-
oberlies about 5 yearsPossible duplicate of JSR-303 @Valid annotation (nested object) not working
-