When using Hibernate Validator (via the javax.validation
interfaces), I'm seeing a strange phenomenon in the property paths of nested objects when there are violations.
This demonstrates it:
@Documented
@Retention(RUNTIME)
@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Constraint(validatedBy = AddressLineValidator.class)
public @interface ValidAddressLine {
String message() default "Address line is invalid.";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
public class AddressLineValidator implements ConstraintValidator<ValidAddressLine, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return value != null && value.length() >= 5;
}
}
public class ValidationPathTest {
@lombok.Builder
static class Person {
private List<@Valid Address> addresses ;
}
@lombok.Builder
static class Address {
private List<@ValidAddressLine String> lines;
}
public static void main(String[] args) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Address address = Address.builder()
.lines(Arrays.asList("221 Baker St.", "B"))
.build();
Person person = Person.builder()
.addresses(Arrays.asList(address))
.build();
Set<ConstraintViolation<Person>> violations = validator.validate(person);
violations.forEach(v -> System.out.println(v.getPropertyPath() + " : " + v.getMessage()));
}
}
This program produces the output
addresses[0].lines[1].<list element> : Address line is invalid.
My question is, why is <list element>
being appended to the property path, and only after the lines[1]
node? The logical follow-up question is, is there some way I can stop or prevent it? Having this in the output out an API endpoint confuses the API users, and I'd like to eliminate it.