Reputation: 18468
Is it possible to tell hibernate validation to validate only one particular annotation ?
I've created custom annotation which use javax.validation.ConstraintValidator
so far so good.
However when I want to manually validate Object using
javax.validation.Validator.validate(myOjbect);
it will validate all annotations including @NotNull, @Size... Is there an elegant way to override this behaviour so I can choose which annotations to validate ?
Upvotes: 0
Views: 1395
Reputation: 6184
I can't find a way to limit validation to a particular annotation without modifying the validated class. You can limit it to a property by calling Validator##validateProperty(object, propertyName, ...)
but the equivalent to explicitly limit it to a set of annotations requires to assign groups to annotations:
What seemes to work is this:
groups
property of each annotation to validate with this group. If the annotation also must be validated by default, add the Default
interface either.An example:
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.groups.Default;
public class SomeTest {
public static void main(String[] args) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Cat a = new Cat(null);
// invalid: name is null
output(validator.validate(a), a);
Cat b = new Cat("?");
// invalid: name too short
output(validator.validate(b), b);
// valid: only @NotNull is evaluated, @Size does not matter.
output(validator.validate(b, NotNullName.class), b);
// invalid: only @NotNull is evaluated, @Size does not matter. Name is null.
output(validator.validate(a, NotNullName.class), a);
}
/**
* Output validation result.
*
* @param validate
* the validate
*/
private static void output(Set<ConstraintViolation<Cat>> validationResult, Cat cat) {
if (validationResult.isEmpty()) {
System.out.println(cat + " is valid!");
} else {
System.out.println(cat + " is invalid!\n" + validationResult);
}
}
// no need to implement an interface - just name it for annotation groups attribute:
public static class Cat {
@NotNull(groups = { NotNullName.class, Default.class })
@Size(min = 3, max = 45)
private String name;
public Cat(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Cat [");
if (name != null) {
builder.append("name=");
builder.append(name);
}
builder.append("]");
return builder.toString();
}
}
public static interface NotNullName {
// no members needed here
}
}
Output:
Cat [] is invalid!
[ConstraintViolationImpl{interpolatedMessage='darf nicht null sein', propertyPath=name, rootBeanClass=class SomeTest$Cat, messageTemplate='{javax.validation.constraints.NotNull.message}'}, ConstraintViolationImpl{interpolatedMessage='darf nicht null sein', propertyPath=name, rootBeanClass=class SomeTest$Cat, messageTemplate='{javax.validation.constraints.NotNull.message}'}]
Cat [name=?] is invalid!
[ConstraintViolationImpl{interpolatedMessage='Länge muss zwischen 3 und 45 liegen', propertyPath=name, rootBeanClass=class SomeTest$Cat, messageTemplate='{javax.validation.constraints.Size.message}'}]
Cat [name=?] is valid!
Cat [] is invalid!
[ConstraintViolationImpl{interpolatedMessage='darf nicht null sein', propertyPath=name, rootBeanClass=class SomeTest$Cat, messageTemplate='{javax.validation.constraints.NotNull.message}'}]
Upvotes: 1