ba0708
ba0708

Reputation: 10599

Hibernate Validator boolean logic

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:

Thank you in advance.

Upvotes: 2

Views: 4177

Answers (1)

Gunnar
Gunnar

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

Related Questions