Nils
(Nils Weinander)
November 14, 2011, 5:28pm
1
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.
Christoph12
(Christoph Guse)
November 15, 2011, 12:26pm
2
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
Nils
(Nils Weinander)
November 16, 2011, 3:57pm
3
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.