Reputation: 10599
I was looking into using boolean logic with my bean validation using Hibernate Validator in scenarios where AND'ing the constraints does not suffice. I found that it is possible to change this default behavior by creating a new annotation with the @ConstraintComposition
annotation as described in the documentation. The documentation provides the following example.
@ConstraintComposition(OR)
@Pattern(regexp = "[a-z]")
@Size(min = 2, max = 3)
@ReportAsSingleViolation
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = { })
public @interface PatternOrSize {
String message() default "{org.hibernate.validator.referenceguide.chapter11." +
"booleancomposition.PatternOrSize.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
Using this @PatternOrSize
validation constraint means that the input string is either lowercased or has a size between 2 and 3. Now this raises a couple of questions:
AND
and OR
at the same time? I could not find anything that suggests that this is possible, but maybe I missed something.@Pattern
and @Size
constraints dynamic? Because otherwise I guess I would have to define a new annotation for every combination of arguments that I need. Defining a new annotation simply to change the arguments to @Size
does not seem feasible, but may be necessary?Thank you in advance.
Upvotes: 2
Views: 4177
Reputation: 18990
I believe one has to create a new annotation to change the default boolean logic behavior. Is this correct?
Yes, that's correct.
Is it possible to further customize the boolean logic behavior without creating a custom validator, e.g. defining AND and OR at the same time?
You might try and create a hierarchically composed constraint (i.e. a constraint composed of other constraints) which uses AND and OR at different levels. I haven't tried it (I don't think we have tests for it) but it may be worth an attempt. Depending on the required boolean logic it may not be suitable for your use case, though.
is it possible to make the arguments to the @Pattern and @Size constraints dynamic?
Yes, you can do so via @OverridesAttribute
:
@ConstraintComposition(OR)
@Pattern(regexp = "[a-z]")
@Size(min = 2, max = 3)
@ReportAsSingleViolation
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = { })
public @interface PatternOrSize {
String message() default "...";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
@OverridesAttribute(constraint=Size.class, name="min")
int min() default 0;
@OverridesAttribute(constraint=Size.class, name="max")
int max() default Integer.MAX_VALUE;
@OverridesAttribute(constraint=Pattern.class, name="regexp")
String regexp();
}
Upvotes: 6