I have strange behaviour using Hibernate Validator (JSR 303) and annotating a property of type java.util.List
Following Code Base:
public class A {
@Valid @NotNull @Size(min=1, max=15)
private List<B<?>> validList = new ArrayList<B<?>>();
...
}
If I start the validation I get the following exception:
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)
If I change my code (and therefore unfortunately my semantic) as follows:
public class A {
@Valid @NotNull @Size(min=0, max=15)
private List<B<?>> validList = new ArrayList<B<?>>();
...
}
everything validates fine without exception.
Which part do I miss? Has anybody an idea why this doesn't work?
I have found out what the problem was. I have a customized constraint on the class B
@CustomConstraint
public class B {
}
the constraint:
@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 {};
}
and the validator:
public class CheckCaseValidator implements ConstraintValidator<CustomConstraint, B<? extends C>> {
... //validation stuff here
}
after I have removed the generics expression from the validator class:
public class CheckCaseValidator implements ConstraintValidator<CustomConstraint, B> {
... //validation stuff here
}
everything worked fine.
Hope that other people find this helpful. Best Regards, Walter
The javadoc ( http://jcp.org/en/jsr/detail?id=303 ) for javax.validation.ConstraintValidator<A, T>
says:
Defines the logic to validate a given constraint A for a given object type T. Implementations must comply to the following restriction:
- T must resolve to a non parameterized type
- or generic parameters of T must be unbounded wildcard types
(T must resolve to a non parameterized type)
that's why ConstraintValidator<CustomConstraint, B>
works
(or generic parameters of T must be unbounded wildcard types)
does not seem to work, as ConstraintValidator<CustomConstraint, B<?>>
does not work either
I also found a different version of the javadoc where the second restriction is left out. So it could be that the official javadoc is just wrong. If you are curious, file a bug report for Hibernate Validator (it's the reference implementation). If you don't - I will ;-)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.