Random42
Random42

Reputation: 9159

Bean Validation validate if one validation is valid?

Suppose there is a bean like this:

public class Car {
     @ConstraintA      
     @ConstraintB
     private String type;

     //getters and setters
}

Normally it is required that both constraints need to be accepted in order for the field to be valid. Is there a possibility in Bean Validation to be configured in a way that if ConstraintA is valid, only then check ConstraintB and only when both fail invalidate the field?

Edit: Some more explaining... Suppose ValidatorA is for ConstraintA and ValidatorB is for ConstraintB. In a typical configuration, Bean Validation works like this:

if (validatorA.isValid(car.type) && validatorB.isValid(car.type)) {
    validate(car);
}

What I want to ask if there is a way of configuring it in doing something like this:

if (validatorA.isValid(car.type) || validatorB.isValid(car.type)) {
    validate(car);
} 

Upvotes: 3

Views: 1694

Answers (1)

guido
guido

Reputation: 19194

I am not sure I get what you are asking, but if you intend to only execute the @Contraint2 validation when @Contraint1 not fails, you can do something like this using JSR-303 groups:

@GroupSequence(value={Car.class, Contraint1Group.class,Contraint2Group.class})
public class Car {

  @ContraintA(groups=Contraint1Group.class)
  @ContraintB(groups=Contraint2Group.class)
  private String type;

}

You need to also declare the marker interfaces to specify the groups:

public interface Contraint1Group extends Default { }

public interface Constraint2Group {}

where the first extending javax.validation.groups.Default is the default one when no group is specified with the constraint annotation.


EDIT after question update: you can, but only if using hibernate validator, which while it is the reference implementation for JSR-303, offers the @ConstraintComposition(OR) extension, while creating new custom composed validation rules:

@ConstraintComposition(OR)
@Constraint1
@Constraint2
@ReportAsSingleViolation
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = { })
public @interface Constraint1ORConstraint2 {
   String message() default "{Constraint1ORConstraint2.message}";
   Class<?>[] groups() default { };
   Class<? extends Payload>[] payload() default { };
}

where @ReportAsSingleViolation means only one violation will be reported per execution (you can have all removing this annotation). As no additional validation is required for the @Constraint1ORConstraint2 annotation itself, don't declare a validator within the @Constraint meta annotation.

Upvotes: 4

Related Questions