Reputation: 11
The ElementType.RECORD_COMPONENT, when applied to annotation for constructor parameter of a record does not work as I would anticipate. I have this record:
public record MyRecord (
MultipartFile document
) {}
I want to ensure that document is file type application/pdf. So I created the annotation:
@Documented
@Target({ElementType.RECORD_COMPONENT})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PdfValidator.class)
public @interface ValidPdf {
String message() default "MultipartFile must be application/pdf type";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
the validator:
public class PdfValidator implements ConstraintValidator<ValidPdf, MultipartFile> {
@Override
public boolean isValid(MultipartFile file, ConstraintValidatorContext context) {
if (file == null) {
return false;
}
return "application/pdf".equals(file.getContentType());
}
}
and applied it to the record:
public record MyRecord (
@ValidPdf
MultipartFile document
) {}
This however doesn't work, the validator is never called. After a few tries I managed to make it work by changing the @Target in PdfValid interface from RECORD_COMPONENT to FIELD.
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PdfValidator.class)
public @interface ValidPdf {
String message() default "MultipartFile must be application/pdf type";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Now it works. But why? Isn't document in MyRecord literally a record component? Why is FIELD the correct value here?
Upvotes: 1
Views: 1220