私は、Spring MVCを使用してフォームのJSR-303検証をセットアップしようとしています。私はすべて正しく構成されていた(少なくとも私がやったと思う)、検証は大部分が正しく機能している。しかし、私が検証したいオブジェクトのコレクションを含むコマンドオブジェクトを持っていて、そのコレクションに@Validを付けると、Hibernate JSR-303プロバイダは正しいpropertyPathを提供していません。 ContraintViolationオブジェクト内のpropertyPathはlist[0].bar
とlist[1].bar
のように設定する必要がありますが、Hibernateバリデーターは単にlist[].bar
とlist[].bar
を提供しています。これにより、SpringのSpringValidatorAdaptor.validate()メソッドがフィールドレベルのエラーを追加しようとしたときにNumberFormatExceptionが発生します(内部的にこれらの大括弧内に数値が存在することが予想されるため)。Hibernate JSR303検証と誤って生成されたpropertyPath
spring-context-3.0.5とhibernate-validator-4.1.0.Final(私も4.0.2.GAと4.2.0.Beta2を試して同じ結果を得ました)を使用して、私は小さなユニットテストを書いています問題を説明するために:
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);
}
}
}
を上記試験は、以下の出力を生成する:
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}'}
それが生成するエラーは正しいです。しかし、propertyPathは(少なくとも私が理解しているものから)ではありません。
ここで、HibernateのJSR-303実装をApache(org.apache.bval.bundle-0.2-incubating - 依存関係をhereとしています)に置き換えると、期待通りの結果が得られます。これはまったく同じテストですが、Hibernateの代わりにApacheのJSR-303アノテーションを使用しています。今のPropertyPathフィールドに存在するインデックスを注意:様々な理由
ConstraintViolationImpl{[email protected], propertyPath='list[0].bar', message='may not be empty', [email protected], value=}
ConstraintViolationImpl{[email protected], propertyPath='list[1].bar', message='may not be empty', [email protected], value=}
、私はおそらくHibernateのJSR-303の実装を使用して立ち往生しています。 Hibernateバリデーターがそれらのインデックスに値を設定しない原因となっている何かがありますか?私は可能な限り私のSpringコントローラで手動エラー処理をしないようにしています。
ご協力いただきありがとうございます。