2011-11-03 61 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(這是參考實現)。如果你不 - 我會;-)