JSR 303 - Проверка гибернации 4.2.0 - UnexpectedTypeException - @Valid и @Size в комбинации - PullRequest
2 голосов
/ 03 ноября 2011

У меня странное поведение при использовании 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

}

все работало нормально.

Надеюсь, что другие люди найдут это полезным.С наилучшими пожеланиями, Уолтер

1 Ответ

1 голос
/ 04 ноября 2011

Javadoc (http://jcp.org/en/jsr/detail?id=303) для javax.validation.ConstraintValidator<A, T> говорит:

Определяет логику для проверки заданного ограничения A для заданного типа объекта T. Реализации должны соответствовать следующему ограничению:

  • T должен разрешить тип без параметризации
  • или универсальные параметры T должны быть неограниченными подстановочными типами
  1. (T должен разрешать тип без параметризации)

    Вот почему ConstraintValidator<CustomConstraint, B> работает

  2. (или универсальные параметры T должны быть неограниченного подстановочного типа)

    не похоже на работу, так как ConstraintValidator<CustomConstraint, B<?>> тоже не работает

Я также нашел другую версию Javadoc, где второе ограничение отсутствует. Так что может быть, что официальный Javadoc просто неправ. Если вам интересно, подайте отчет об ошибке для Hibernate Validator (это эталонная реализация). Если нет - я буду; -)

...