[java] Annotations from javax.validation.constraints not working

What configuration is needed to use annotations from javax.validation.constraints like @Size, @NotNull, etc.? Here's my code:

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Person {
      @NotNull
      private String id;

      @Size(max = 3)
      private String name;

      private int age;

      public Person(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
      }
}

When I try to use it in another class, validation doesn't work (i.e. the object is created without error):

Person P = new Person(null, "Richard3", 8229));

Why doesn't this apply constraints for id and name? What else do I need to do?

This question is related to java spring annotations constraints bean-validation

The answer is


You should use Validator to check whether you class is valid.

Person person = ....;
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(person);

Then, iterating violations set, you can find violations.


So @Valid at service interface would work for only that object. If you have any more validations within the hierarchy of ServiceRequest object then you might to have explicitly trigger validations. So this is how I have done it:

public class ServiceRequestValidator {

      private static Validator validator;

      @PostConstruct
      public void init(){
         validator = Validation.buildDefaultValidatorFactory().getValidator();
      }

      public static <T> void validate(T t){
        Set<ConstraintViolation<T>> errors = validator.validate(t);
        if(CollectionUtils.isNotEmpty(errors)){
          throw new ConstraintViolationException(errors);
        }
     }

}

You need to have following annotations at the object level if you want to trigger validation for that object.

@Valid
@NotNull

I come here some years after, and I could fix it thanks to atrain's comment above. In my case, I was missing @Valid in the API that receives the Object (a POJO in my case) that was annotated with @Size. It solved the issue.

I did not need to add any extra annotation, such as @Valid or @NotBlank to the variable annotated with @Size, just that constraint in the variable and what I mentioned in the API...

Pojo Class:

...
@Size(min = MIN_LENGTH, max = MAX_LENGTH);
private String exampleVar;
...

API Class:

...
public void exampleApiCall(@RequestBody @Valid PojoObject pojoObject){
  ...
}

Thanks and cheers


In my case i removed these lines

1-import javax.validation.constraints.NotNull;

2-import javax.validation.constraints.Size;

3- @NotNull

4- @Size(max = 3)


I came across this problem recently in a very similar situation: Met all requirements as the top-rated answer listed but still got the wrong result.

So I looked at my dependencies and found I was missing some of them. I corrected it by adding the missing dependencies.

I was using hibernate, the required dependencies were: Dependencies Snapshot

*Snapshot taken in class "Spring & Hibernate for Beginners" @ Udemy


After the Version 2.3.0 the "spring-boot-strarter-test" (that included the NotNull/NotBlank/etc) is now "sprnig boot-strarter-validation"

Just change it from ....-test to ...-validation and it should work.

If not downgrading the version that you are using to 2.1.3 also will solve it.


You can also simply use @NonNull with the lombok library instead, at least for the @NotNull scenario. More details: https://projectlombok.org/api/lombok/NonNull.html


You need to add @Valid to each member variable, which was also an object that contained validation constraints.


If you are using lombok then, you can use @NonNull annotation insted. or Just add the javax.validation dependency in pom.xml file.


for method parameters you can use Objects.requireNonNull() like this: test(String str) { Objects.requireNonNull(str); } But this is only checked at runtime and throws an NPE if null. It is like a preconditions check. But that might be what you are looking for.


You would have to call a Validator on the Entity if you want to validate it. Then you will get a set of ConstraintViolationException, which basically show for which field/s of your Entity there is a constraint violation and what exactly was it. Maybe you can also share some of the code you expect to validate your entity.

An often used technique is to do validation in @PrePersist and rollback transaction if using multiple data modifications during transaction or do other actions when you get a validation exception.

Your code should go like this:

@PrePersist
public void prePersist(SomeEntity someEntity){
    Validator validator = Validation.buildDefaultValidatorFactory.getValidator();
    Set<ConstraintViolation<SomeEntity>> = validator.validate(someEntity);
    //do stuff with them, like notify client what was the wrong field, log them, or, if empty, be happy
}

in my case i had a custom class-level constraint that was not being called.

@CustomValidation // not called
public class MyClass {
    @Lob
    @Column(nullable = false)
    private String name;
}

as soon as i added a field-level constraint to my class, either custom or standard, the class-level constraint started working.

@CustomValidation // now it works. super.
public class MyClass {
    @Lob
    @Column(nullable = false)
    @NotBlank // adding this made @CustomValidation start working
    private String name;
}

seems like buggy behavior to me but easy enough to work around i guess


Great answer from atrain, but maybe better solution to catch exceptions is to utilize own HandlerExceptionResolver and catch

@Override
public ModelAndView resolveException(
    HttpServletRequest aReq, 
    HttpServletResponse aRes,
    Object aHandler, 
    Exception anExc
){
    // ....
    if(anExc instanceof MethodArgumentNotValidException) // do your handle     error here
}

Then you're able to keep your handler as clean as possible. You don't need BindingResult, Model and SomeFormBean in myHandlerMethod anymore.


In my case, I was using spring boot version 2.3.0. When I changed my maven dependency to use 2.1.3 it worked.

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.3.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
    </dependency>
</dependencies>

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to spring

Are all Spring Framework Java Configuration injection examples buggy? Two Page Login with Spring Security 3.2.x Access blocked by CORS policy: Response to preflight request doesn't pass access control check Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified Spring Data JPA findOne() change to Optional how to use this? After Spring Boot 2.0 migration: jdbcUrl is required with driverClassName The type WebMvcConfigurerAdapter is deprecated No converter found capable of converting from type to type

Examples related to annotations

How to inject a Map using the @Value Spring Annotation? intellij incorrectly saying no beans of type found for autowired repository @Autowired - No qualifying bean of type found for dependency Difference between @Before, @BeforeClass, @BeforeEach and @BeforeAll Can't find @Nullable inside javax.annotation.* Name attribute in @Entity and @Table Get rid of "The value for annotation attribute must be a constant expression" message @Value annotation type casting to Integer from String What does -> mean in Python function definitions? @Nullable annotation usage

Examples related to constraints

How to trap on UIViewAlertForUnsatisfiableConstraints? trying to animate a constraint in swift Remove all constraints affecting a UIView "Insert if not exists" statement in SQLite Unique Key constraints for multiple columns in Entity Framework SQL Server 2008- Get table constraints How to remove constraints from my MySQL table? Creating layout constraints programmatically Display names of all constraints for a table in Oracle SQL Add primary key to existing table

Examples related to bean-validation

JSR 303 Validation, If one field equals "something", then these other fields should not be null Annotations from javax.validation.constraints not working Cross field validation with Hibernate Validator (JSR 303)