Is it possible to create a constraint annotation, that targets an interface but can be used to validate any concrete implementation that implements said interface?
For example, we have interface Identifiable:
public interface Identifiable {
String getId();
}
I'd like to create a constraint, that targets List<Identifiable>:
@Documented
@Constraint(validatedBy = IdentifiablesValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Identifiables {
// ...Constraint properties...
}
public class IdentifiablesValidator implements ConstraintValidator<Identifiables, List<Identifiable>> {
// ...Validator logic...
}
And then apply the constraint to a target that implements the interface:
public class SomeExampleCase {
@Identifiables()
List<IdentifiableImpl> sut;
}
But at runtime this results in an error:
javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'com.example.Identifiables' validating type 'java.util.List<com.example.IdentifiableImpl>'. Check configuration for 'identifiables'
The constraint does work for validation, when applied to a list of the interface (e.g. List<Identifiable>). But this forces the target class (e.g. SomeExampleCase) to use the interface, rather than an implementation - which gets in the way of all types of things (e.g. Marshalling/Unmarshalling).
Is there a way to get the validator to work with an actual List<Identifiable>, without rewriting it to target `List?
Thanks in advance!
Update 1: The same issue occurs when the interface is turned into an abstract class.
I came here with the same question and after some trials I got this working for me:
@Documented
@Constraint(validatedBy = IdentifiablesValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Identifiables {
// ...Constraint properties...
}
public class IdentifiablesValidator implements ConstraintValidator<Identifiables, List<? extends Identifiable>> {
// ...Validator logic...
}
The important part is the change of <? extends Interface>.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With