Using version Hibernate Validator 4.3.0.Final.
When I make the following call:
Set<ConstraintViolation<T>> violations = validator.validateProperty(objectForValidation, "list[0].field1", groups);
on an instance of ClassForValidation populated with one instance of ChildClassForValidation with field1 = ""
public class ClassForValidation {
@NotEmpty
private String fielda;
@Valid
private List<ChildClassForValidation> list = new ArrayList<ChildClassForValidation>();
public ClassForValidation(List<> list, String fielda) {
this.list = list;
this.fielda = fielda;
}
}
public class ChildClassForValidation {
@NotEmpty
private String field1;
public ChildClassForValidation(String field1) {
this.field1 = field1;
}
}
I get the follwing exception:
java.lang.IllegalArgumentException: HV000039: Invalid property path. There is no property field1 in entity java.util.ArrayList.
at org.hibernate.validator.internal.engine.ValidatorImpl.collectMetaConstraintsForPath(ValidatorImpl.java:1141)
at org.hibernate.validator.internal.engine.ValidatorImpl.collectMetaConstraintsForPath(ValidatorImpl.java:1179)
at org.hibernate.validator.internal.engine.ValidatorImpl.validatePropertyInContext(ValidatorImpl.java:616)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateProperty(ValidatorImpl.java:151)
...
After looking into the Hibernate Validator source I have come to the conclusion that this is a bug. For in the source there appears to be code attempting to handle both lists and maps. I believe the error lies in the following piece of code in org.hibernate.validator.internal.engine.ValidatorImpl
private <T, U, V> ValueContext<U, V> collectMetaConstraintsForPath(Class<T> clazz, Object value, Iterator<Path.Node> propertyIter, PathImpl propertyPath, List<MetaConstraint<?>> metaConstraintsList) {
Path.Node elem = propertyIter.next();
Object newValue = value;
BeanMetaData<?> metaData = beanMetaDataManager.getBeanMetaData( clazz );
//use precomputed method list as ReflectionHelper#containsMember is slow
if ( !metaData.isPropertyPresent( elem.getName() ) ) {
throw log.getInvalidPropertyPathException( elem.getName(), metaData.getBeanClass().getName() );
}
...
}
In this piece of code it verifies that clazz has the property being validated, the problem is that when processing field1, clazz is ArrayList instead of the item(0)'s class (i.e. ChildClassForValidation).
I would like to confirm my findings before submitting a bug to the Hibernate Validator project. Who knows I might just have the wrong syntax for my property path.
As of Bean Validation 1.0, Validator#validateProperty()
supports only the validation of single properties, but not complete property paths. As discussed on the BV mailing list, such a feature might be supported in future revisions of the spec.