我使用Hibernate Validator(JSR 303)并注释java.util.List类型的属性有奇怪的行为
遵循代码库:
public class A {
@Valid @NotNull @Size(min=1, max=15)
private List<B<?>> validList = new ArrayList<B<?>>();
...
}
如果我开始验证,我会得到以下异常:
javax.validation.UnexpectedTypeException: No validator could be found for type: B
at org.hibernate.validator.engine.ConstraintTree.verifyResolveWasUnique(ConstraintTree.java:383)
at org.hibernate.validator.engine.ConstraintTree.findMatchingValidatorClass(ConstraintTree.java:364)
at org.hibernate.validator.engine.ConstraintTree.getInitializedValidator(ConstraintTree.java:313)
at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree.java:144)
at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree.java:117)
at org.hibernate.validator.metadata.MetaConstraint.validateConstraint(MetaConstraint.java:84)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:452)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:397)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:361)
at org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:313)
at org.hibernate.validator.engine.ValidatorImpl.validateCascadedConstraint(ValidatorImpl.java:613)
at org.hibernate.validator.engine.ValidatorImpl.validateCascadedConstraints(ValidatorImpl.java:478)
at org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:322)
at org.hibernate.validator.engine.ValidatorImpl.validate(ValidatorImpl.java:139)
如果我更改我的代码(因此不幸的是我的语义)如下:
public class A {
@Valid @NotNull @Size(min=0, max=15)
private List<B<?>> validList = new ArrayList<B<?>>();
...
}
一切都经过验证,无一例外。
我想念哪一部分?有谁知道为什么这不起作用?
我发现了问题所在。我对B类有一个自定义约束
@CustomConstraint
public class B {
}
约束:
@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = CustomConstraintValidator.class)
@Documented
public @interface CustomConstraint {
String message() default "{com.mycompany.constraints.checkcase}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
和验证器:
public class CheckCaseValidator implements ConstraintValidator<CustomConstraint, B<? extends C>> {
... //validation stuff here
}
我从验证器类中删除了泛型表达式:
public class CheckCaseValidator implements ConstraintValidator<CustomConstraint, B> {
... //validation stuff here
}
一切正常。
希望其他人觉得这很有帮助。 最好的祝福, 沃尔特
答案 0 :(得分:1)
javax.validation.ConstraintValidator<A, T>
的javadoc(http://jcp.org/en/jsr/detail?id=303)说:
定义为给定对象类型T验证给定约束A的逻辑。实现必须符合以下限制:
- T必须解析为非参数化类型
- 或T的通用参数必须是无界通配符类型
(T必须解析为非参数化类型)
这就是ConstraintValidator<CustomConstraint, B>
工作的原因
(或T的通用参数必须是无界通配符类型)
似乎不起作用,因为ConstraintValidator<CustomConstraint, B<?>>
不起作用
我还找到了different version的javadoc,其中省略了第二个限制。所以可能是官方的javadoc是错的。如果你很好奇,file a bug report for Hibernate Validator(这是参考实现)。如果你不这样做 - 我会; - )