We can use the Composite Constraint feature to compose many Bean Validation's annotations into a single one custom annotation/validation, as the following code:
import org.hibernate.validator.constraints.CompositionType;
import org.hibernate.validator.constraints.ConstraintComposition;
import org.hibernate.validator.constraints.br.CNPJ;
import org.hibernate.validator.constraints.br.CPF;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@CPF
@CNPJ
@ConstraintComposition(CompositionType.OR) // specifies OR as boolean operator instead of AND
@ReportAsSingleViolation // the error reports of each individual composing constraint are ignored
@Constraint(validatedBy = { }) // we don't need a validator :-)
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CPFOrCNPJ {
String message() default "it's not a valid CPF or CNPJ";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}Here are some interesting links about this feature:
- Bean Validation Spec: Constraint composition
- Constraint Composition Spec Proposal in 2008
- Hibernate Documentation: Constraint Composition
- Hibernate Documentation: Advanced constraint composition features -
@OverridesAttributeand@ConstraintComposition(OR) - Hibernate Documentation: Fail fast mode
- StackOverflow: Unifying error messages with
@ReportAsSingleViolation - StackOverflow:
@ReportAsSingleViolationandhibernate.validator.fail_fastproperty - Hibernate Javadoc: Annotation Type ConstraintComposition
- Hibernate Example: @PatternOrSize
The same custom annotation in Kotlin: