Consider this code
import org.hibernate.validator.constraints.Range;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.Set;
class Scratch {
public static void main(String[] args) {
final Person alice = new Person("Alice", 54, Optional.of("Tiddles"));// Valid has pet with valid name
final Person frank = new Person("Frank", 75, Optional.of(" ")); // Should be invalid pet name is blank
final Person oliver = new Person("Oliver", 75, null); // Should be invalid pet name is null
final Person bob = new Person("Bob", 33, Optional.empty()); // Valid no pet
final List<Person> people = List.of(alice, frank, oliver, bob);
final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
for (Person person : people) {
final Set<ConstraintViolation<Person>> violations = validator.validate(person);
if (violations.isEmpty()) {
System.out.println(String.format( "[%s] is valid", person.name));
} else {
System.out.println(String.format("[%s] is invalid [%s]", person.name, violations));
}
}
}
static class Person {
@NotBlank
public String name;
@Range(min = 0, max = 150)
public int age;
@NotNull
public Optional<@NotBlank String> petsName;
public Person(String name, int age, Optional<String> petsName) {
this.name = name;
this.age = age;
this.petsName = petsName;
}
}
}
The question is how to validate Optional
fields. Its valid for petsName to be an empty Optional (i.e. no pet) but if there is a pet it should have a valid (i.e. non-blank) name.
When I run this code it outputs
Dec 22, 2021 11:50:25 AM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 6.1.7.Final
[Alice] is valid
[Frank] is invalid [[ConstraintViolationImpl{interpolatedMessage='must not be blank', propertyPath=petsName, rootBeanClass=class Scratch$Person, messageTemplate='{javax.validation.constraints.NotBlank.message}'}]]
[Oliver] is invalid [[ConstraintViolationImpl{interpolatedMessage='must not be null', propertyPath=petsName, rootBeanClass=class Scratch$Person, messageTemplate='{javax.validation.constraints.NotNull.message}'}]]
[Bob] is invalid [[ConstraintViolationImpl{interpolatedMessage='must not be blank', propertyPath=petsName, rootBeanClass=class Scratch$Person, messageTemplate='{javax.validation.constraints.NotBlank.message}'}]
So its close to working. Only the last case of bob is wrong. Is there any obvious solution i'm missing?