JSR 303: How to Validate a Collection of annotated objects?

JavaBean ValidationHibernate ValidatorJsr

Java Problem Overview


Is it possible to validate a collection of objects in JSR 303 - Jave Bean Validation where the collection itself does not have any annotations but the elements contained within do?

For example, is it possible for this to result in a constraint violation due to a null name on the second person:

List<Person> people = new ArrayList<Person>();
people.add(new Person("dave"));
people.add(new Person(null));

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<List<Person>>> validation = validator.validate(people);

Java Solutions


Solution 1 - Java

Yes, just add @Valid to the collection.

Here is an example from the Hibernate Validator Reference.

public class Car {
  @NotNull
  @Valid
  private List<Person> passengers = new ArrayList<Person>();
}

This is standard JSR-303 behavior. See Section 3.1.3 of the spec.

Solution 2 - Java

You, can also add @NotEmpty to the collection.

public class Car {
  @NotEmpty(message="At least one passenger is required")
  @Valid
  private List<Person> passengers = new ArrayList<Person>();
}

this will ensure at least one passenger is present, and the @Valid annotation ensures that each Person object is validated

Solution 3 - Java

You can of course also just iterate over the list and call Validator.validate on each element. Or put the List into some wrapper bean and annotate it with @Valid. Extending ArrayList for validation seems wrong to me. Do you have a particular use case you want to solve with this? If so maybe you can explain it a little more. To answer your initial question:

> Is it possible to validate a > collection of objects in JSR 303 - > Jave Bean Validation where the > collection itself does not have any > annotations but the elements contained > within do?

No

Solution 4 - Java

As of Bean Validator 2.0, both of these approaches work:

class MyDto {

    private List<@Valid MyBean> beans;
}

and

class MyDto {

    @Valid
    private List<MyBean> beans;
}

Solution 5 - Java

I wrote this generic class:

public class ValidListWrapper<T> {

    @Valid
    private List<T> list;

    public ValidListWrapper(List<T> list) {
        this.list = list;
    }

    public List<T> getList() {
        return list;
    }

}

If you are using Jackson library to deserialize JSON you can add @JsonCreator annotation on the constructor and Jackson will automatically deserialize JSON array to wrapper object.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncamView Question on Stackoverflow
Solution 1 - JavasourcedelicaView Answer on Stackoverflow
Solution 2 - Javadezzer10View Answer on Stackoverflow
Solution 3 - JavaHardyView Answer on Stackoverflow
Solution 4 - JavaHamid MohayejiView Answer on Stackoverflow
Solution 5 - Javaholmis83View Answer on Stackoverflow