2011-11-03 62 views
2

我使用Hibernate的验证(JSR 303)的奇怪行为和注释java.util.List类型JSR 303 - Hibernate的验证4.2.0 - UnexpectedTypeException - @Valid和@Size组合

的下面的代码基础属性:

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

你确定这与'@ Size'有关吗?对我来说,只有'@ Valid'存在时也会发生同样的异常。 – jeha

回答

1

javax.validation.ConstraintValidator<A, T>的JavaDoc(http://jcp.org/en/jsr/detail?id=303)表示:

定义逻辑来验证给定约束的用于给定对象类型T.实现必须符合下列限制:

  • T必须解决一个非参数化的类型
  • 或通用的T参数必须是无界的通配符类型
  1. (T必须解决到非参数化类型)

    这就是为什么ConstraintValidator<CustomConstraint, B>工作

  2. (T的或通用的参数必须是无界的通配符类型)

    似乎不工作,因为ConstraintValidator<CustomConstraint, B<?>>无法正常工作或

我还发现的Javadoc的different version其中第二个限制被排除在外。所以官方的javadoc可能是错的。如果您好奇,file a bug report for Hibernate Validator(这是参考实现)。如果你不 - 我会;-)