Howto validate Collections in Maps

hibernate-validator, java, validation

Solution

The specification does not specify the validation behavior when the map values are themselves lists.

From JSR 303 specification:

Each object provided by the iterator is validated. For Map, the value of each Map.Entry is validated (the key is not validated).

Since the value in your case is a list, which does not have a @Valid annotation, it does not get processed. To get around this you can either:

Wrap the contained list in another bean, forcing the annotation processing onto the list.

public class ListHolder<T extends Iterable> {
    @Valid
    public T wrappedList;
}

Or alternatively you can write a custom validator to handle your complex maps. Something like this:

@Target({ METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ValidMapValidator.class)
public @interface ValidMap {
   String message() default "valid.map";

   Class<?>[] groups() default {};

   Class<? extends Payload>[] payload() default {};
}

public class ValidMapValidator implements
      ConstraintValidator<ValidMap, Map<?, ?>> {

   @Override
   public void initialize(final ValidMap annotation) {
      return;
   }

   @Override
   public boolean isValid(final Map<?, ?> map,
         final ConstraintValidatorContext context) {
      if (map == null || map.size() == 0)
         return true;

      // Iterate each map entry and validate
      return true;
   }
}

Problem

I have a problem with the `@Valid` annotation of JSR-303. The annotation works fine for normal lists or and sets, but I am trying to validate Maps which contain Lists, i.e. ``` @Valid HashMap<String, ArrayList<Object1>> map; ``` In this case, instances of `Object1` class are not validated. Is there a convenient way to do this recursively, without iterating over every object and validating it manually?

Original source