Spring/Hibernate - validating groups manually and return a BindingResult

hibernate-validator, spring, spring-mvc

Solution

I had a similar issue, and ended up extending the SpringValidatorAdapter class so that I could perform the validation and specify the groups.

ExtendedSpringValidatorAdapter adapter = new ExtendedSpringValidatorAdapter(validator);
adapter.validate(objectToValidate, bindingResult, Class1.class, Class2.class);

Here is the definition of the extended validator:

package com.example.validator;

import org.springframework.beans.NotReadablePropertyException;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.groups.Default;
import java.util.Set;

public class ExtendedSpringValidatorAdapter extends SpringValidatorAdapter {

    // ========================================================================
    // ========================================================================
    // ========================================================================
    public ExtendedSpringValidatorAdapter(Validator targetValidator) {
        super(targetValidator);
    }

    // ========================================================================
    // ========================================================================
    // ========================================================================
    public void validate(Object target, Errors errors, Class<?>... groups) {

        if (groups == null || groups.length == 0 || groups[0] == null) {
            groups = new Class<?>[]{Default.class};
        }

        Set<ConstraintViolation<Object>> result = validate(target, groups);
        for (ConstraintViolation<Object> violation : result) {
            String field = violation.getPropertyPath().toString();
            FieldError fieldError = errors.getFieldError(field);
            if (fieldError == null || !fieldError.isBindingFailure()) {
                try {
                    errors.rejectValue(field,
                            violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(),
                            getArgumentsForConstraint(errors.getObjectName(), field, violation.getConstraintDescriptor()),
                            violation.getMessage());
                } catch (NotReadablePropertyException ex) {
                    throw new IllegalStateException("JSR-303 validated property '" + field +
                            "' does not have a corresponding accessor for Spring data binding - " +
                            "check your DataBinder's configuration (bean property versus direct field access)", ex);
                }
            }
        }
    }
}

Problem

I want to manually validate (not using @Valid or @Validated) using groups and return a BindingResult. I have a spring validator configured ``` <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" > <property name="validationMessageSource" ref="messageSource"/> </bean> ``` And this is the class that does the validation, it works but notice that `groups` is not being used. ``` @Component public class ObjectValidatorImpl implements ObjectValidator { private final Validator validator; @Autowired public ObjectValidatorImpl(final Validator validator) { super(); this.validator = validator; } @Override public final <T> BindingResult getBindingResults( final T objectToValidate, final Class<?>...groups) { final DataBinder binder = new DataBinder(objectToValidate); binder.setValidator(validator); //ideally, I would like to set the groups on the binder here like //binder.setGroups(groups); binder.validate(); return binder.getBindingResult(); } } ``` I cant figure out how to get the Validator to use the groups, the seems to be no method for it. I would like to call it like this. ``` objectValidator.validate(myObject, Class1.class, Class2.class) ```

Original source