BeanValidationForm and @Valid

I use a bean with a @Valid annotation for nested validation with a BeanValidationForm (version 0.6.2)


	@Valid
	public Set<SimplePhotoModel> getPhotos() {
		return photos;
	}
 

I can verify in the debugger that I get to the call


        Set<?> violations = validator.validateValue(beanClass, propertyName,
                convertedValue);
 

but what should be an invalid SimplePhotoModel doesn’t cause any violations. Any ideas what I’m doing wrong? I have included hibernate-validator-annotation-processor version 4.2.0.Final for the actual JSR-303 validation.

Hi Nils,

I think you are doing everything right, the Hibernate Validation implementation simply does nut provide the @Valid functionality for validateProperty() or validateValue().

See chapter 2.2.2.3. validateValue in
Hibernate Documentation
.

Currently I’m having the same problem and no solution for it.

Regards,
Christoph

Christoph,

You are quite right, I debugged it with both Hibernate Validation and Apache Bval and neither heeds @Valid for validateValue(), which is what BeanValidationValidator uses. I have solved it with my own custom validation and annotation:


package no.anastazia.web.validation;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = NestedValidator.class)
@Documented
public @interface Nested {

    String message() default "{invalid.nested}";

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

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

}

/**
 * 
 */
package no.anastazia.web.validation;

import java.util.Iterator;
import java.util.Set;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;

/**
 * @author nils
 *
 */
public class NestedValidator implements ConstraintValidator<Nested, Object> {
	
	private Class<?> classToValidate;

    private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    private transient javax.validation.Validator validator;

	/* (non-Javadoc)
	 * @see javax.validation.ConstraintValidator#initialize(java.lang.annotation.Annotation)
	 */
	@Override
	public void initialize(Nested constraintAnnotation) {
		classToValidate = constraintAnnotation.value();
        validator = factory.getValidator();
	}

	/* (non-Javadoc)
	 * @see javax.validation.ConstraintValidator#isValid(java.lang.Object, javax.validation.ConstraintValidatorContext)
	 */
	@Override
	public boolean isValid(Object value, ConstraintValidatorContext context) {
		boolean valid = true;
		
		if(value instanceof Iterable) {
			Iterator<?> iterator = ((Iterable<?>) value).iterator();
			while(iterator.hasNext()) {
				Object validatee = iterator.next();
				valid = valid && validate(validatee);
				if(!valid) {
					break;
				}
			}
		} else {
			valid = validate(value);
		}

		return valid;
	}

	private boolean validate(Object validatee) {
		if(validatee.getClass().isAssignableFrom(classToValidate)) {
			Set<ConstraintViolation<Object>> violations = validator.validate(validatee);
			return (violations.size() == 0);
		} else {
			return false;
		}
	}

}

...

	@Nested(value=SimplePhotoModel.class, message="{invalid.simplePhoto}")
	public Set<SimplePhotoModel> getPhotos() {
		return photos;
	}

...

 

I still haven’t manage to get a reasonable display of validation errors. I have set setValidationVisible(false) on the “sub-form”, but get ugly error markers on individual fields.