Hibernate JSR303 validation and incorrectly generated Path property

I am trying to customize validation of JSR-303 forms using Spring MVC. Everything is set up correctly for me (or, at least, I think it is), and the checks work mostly correctly. However, if I have a command object that contains a collection of objects that I want to test, and I comment on this collection with @Valid, the Hibernate JSR-303 provider does not provide the correct propertyPath. The Property property inside the ContraintViolation object must be populated as list[0].bar and list[1].bar , but the Hibernate validator simply provides list[].bar and list[].bar . This throws a NumberFormatException when the Spring SpringValidatorAdaptor.validate () method tries to add field level errors (since it internally expects the number to exist in these brackets).

Using spring -context-3.0.5 and hibernate-validator-4.1.0.Final (I also tried 4.0.2.GA and 4.2.0.Beta2 and got the same results), I wrote a small unit test to illustrate the problem:

 package com.foo; import java.util.ArrayList; import java.util.Collection; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Valid; import javax.validation.Validation; import javax.validation.Validator; import org.hibernate.validator.constraints.NotEmpty; import org.junit.Test; import org.springframework.util.AutoPopulatingList; public class ValidatorTest { class Person { @NotEmpty private String name; @NotEmpty @Valid private Collection<Foo> list = new AutoPopulatingList<Foo>(Foo.class); public void setName(String name) { this.name = name; } public String getName() { return name; } public Collection<Foo> getList() { return list; } public void setList(Collection<Foo> foos) { this.list = foos; } } class Foo { @NotEmpty private String bar; public void setBar(String bar) { this.bar = bar; } public String getBar() { return bar; } } @Test public void testValidator() throws Exception { Foo foo0 = new Foo(); foo0.setBar(""); Foo foo1 = new Foo(); foo1.setBar(""); Collection<Foo> list = new ArrayList<ValidatorTest.Foo>(); list.add(foo0); list.add(foo1); Person person = new Person(); person.setName("Test Person"); person.setList(list); Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); Set<ConstraintViolation<Person>> violations = validator.validate(person); for (ConstraintViolation<Person> constraintViolation : violations) { System.out.println(constraintViolation); } } } 

The above test gives the following result:

 ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=list[].bar, rootBeanClass=class com.foo.ValidatorTest$Person, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'} ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=list[].bar, rootBeanClass=class com.foo.ValidatorTest$Person, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'} 

The errors that he makes are correct; however, the Path property is not (at least from what I understand).

Now, if I replaced the Hibernate JSR-303 implementation with Apache (org.apache.bval.bundle-0.2-incubating) using the specified dependencies here ), I get the output that I expect. This is the same test, but using Apache JSR-303 annotations instead of Hibernate. Notice the indexes that now exist in the propertyPath field:

 ConstraintViolationImpl{ rootBean=com.foo.ValidatorTest$Person@5f989f84 , propertyPath='list[0].bar', message='may not be empty', leafBean=com.foo.ValidatorTest$Foo@4393722c , value=} ConstraintViolationImpl{ rootBean=com.foo.ValidatorTest$Person@5f989f84 , propertyPath='list[1].bar', message='may not be empty', leafBean=com.foo.ValidatorTest$Foo@528acf6e , value=} 

For various reasons, I probably stick with the use of Hibernate JSR-303. Is there something I am doing that makes the Hibernate validator not populate these indexes? I try to avoid manually managing errors in my Spring controllers as much as possible.

Thanks for any help you can provide!

+4
source share

All Articles