@NotNull annotation is not working in Spring boot application
Asked Answered
B

4

23

Below is my DTO class.

public class AbstractDTO extends BaseDTO {

    private Integer createdBy;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DATE_FORMAT)
    @NotNull(message = "createdDate may not be null")
    private LocalDateTime createdDate;

    private Integer lastModifiedBy;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DATE_FORMAT)
    private LocalDateTime lastModifiedDate;

    private Boolean isActive;

    // getter & setters
}

Here I am trying to annotate createdDate field as @NotNull but is it not working. It is allowing in request body and after executing the service in postman not getting any error.

I have tried below options but no luck.

1) Tried to add maven dependency.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2) Tried to annotate DTO class as @Validated

3) Tried to annotate createdDate field @Valid with @NotNull but still not luck.

Please help me out with this issue.

Barometer answered 1/10, 2019 at 10:8 Comment(4)
Did you try to annotate the DTO class as @Validated in the controller method signature ? something like void foo(@Validated MyDTO dto)Rosy
@ArnaudDenoyelle This DTO has been used in multiple location more than 25 files, Do I have to make changes in every file? Is there any other solution?Barometer
Does you app has starter - spring-boot-starter-web which will load hibernate Validator to dependency. Which will validate the bean. Please go through this link - #48200944Effeminize
Check my answer, it should resolve your issue. But if @NotNull does not work while @JsonPattern works, then it might be the case with the wrong @NotNull being used. Otherwise it seems you forgot adding @Valid on your controller method.Carmon
A
20

Your DTO class is correct. You have to use @Valid annotation.

For example :

@Controller
public class Controller {

    @PostMapping("/")
    public String checkPersonInfo(@Valid AbstractDTO abstractDTO, BindingResult bindingResult) {

        if (bindingResult.hasErrors()) {
            return "some-page";
        }
        return "some-other-page";
    }
}

Refer to this Spring Boot Example On Validating Form Input for reference.

Why to use @Valid annotation ?

This allows you to validate the set of constraints applied on the data members of a class.


However, if you have XML based configuration in your project, then you have to add this below in the applicationContext.xml given below. (Source : here)

<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="webBindingInitializer">
        <bean
            class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="validator" ref="validator" />
        </bean>
    </property>
</bean> 

    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    </bean>
Antipersonnel answered 1/10, 2019 at 10:14 Comment(0)
S
9

You have an endpoint with some request body like;

@RestController
public class TheController {

    @PostMapping(path = "/doSomething", consumes = "application/json", produces = "application/json")
    public void post(@Valid @RequestBody AbstractDTO request) {
        //code
    }
}

You need to have @Valid annotation for the request object. Only with this you'd have validation enabled for AbstractDTO for /doSomething endpoint.

Check here, for more in depth details

Sherwood answered 1/10, 2019 at 10:15 Comment(0)
H
6

Have you got the right import ?
I use import javax.validation.constraints.NotNull;

Hinduism answered 1/10, 2019 at 10:10 Comment(0)
M
3

Description

  1. In my case, I define 1 parent class A has 3 sub class B, C, D such as:

public A { private B bCommand; private C cCommand; private D dCommand; }

  1. I annotated @NotNull, @NotBlank for some fields in 3 sub class. In Controller, I have put @Valid for function like that:

@PostMapping() public ResponseEntity create(@RequestBody @Valid A
command){ }

Solution

  1. I put @Valid for sub class which has field(s) need to check constraint.
  2. Example: Class B, C have some fields which have constraint like not null

public A { @Valid private B bCommand; @Valid private C cCommand; private D dCommand; }

Marcie answered 17/12, 2022 at 8:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.