0

I'm working on spring boot validation. I have model with two fields.

public class clazz{
     @Min(value ="0")
     private int min;
    
     private int max;
}

I want a validation for max filed that max hasn't value equals or lower than min value, for instance, if min = 5 then max > 5.

majid_shoorabi
  • 121
  • 1
  • 1
  • 16
  • Does this answer your question? [How can I validate two or more fields in combination?](https://stackoverflow.com/questions/2781771/how-can-i-validate-two-or-more-fields-in-combination) – slauth Aug 31 '21 at 07:17

1 Answers1

0

You can define a custom hibernate validator to do cross-field checking. Based on your class, you can see the following code on how to implement such a custom validator.

In summary, we need to:

  1. Add the hibernate-validator dependency in the pom file
  2. Define an annotation using the @interface keyword.
  3. Implement the interface we coded in step 2.
  4. Add the constraint to the domain class.

Note, I have set the validator to be a class-level validator, not a single field validator. I chose this because if the validation fails, it could be that either the max value or the min value is wrong, but we (probably) can't know which.

I provide a summary, and for more information I would refer you to the official hibernate validator documentation.

Adding the dependency in the pom file:

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.2.0.Final</version>
        </dependency>

Defining the annotation: Here, settings define 1) that the validator will be applied to the class-level, 2) which class will implement the validation, and 3) the error message to show.

package com.example.validatorsnippet.validator;

// imports 

@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = CheckValuesValidator.class)
public @interface CheckValues {

    String message() default "Maximum needs to be larger than the minimum value entered";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

Implementing the validator:

package com.example.validatorsnippet.validator;

// imports

public class CheckValuesValidator implements ConstraintValidator<CheckValues, Clazz> {

    @Override
    public boolean isValid(Clazz clazz, ConstraintValidatorContext constraintValidatorContext) {
      return clazz.getMin() < clazz.getMax();
    }
}

Adding the constraint to the class:

package com.example.validatorsnippet.domain;

// imports

@CheckValues
public class Clazz {

    @Min(value =0)
    private int min;

    private int max;

// getters and setters
}

Testing/previewing the validator: In Spring boot we can add a CommandLineRunner implementation to run custom code, so here is one such example which illustrates the use of the above validator.

package com.example.validatorsnippet.runners;

// imports

@Component
public class ValidationExample implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        Clazz clazz = new Clazz();
        clazz.setMin(5);
        clazz.setMax(3);
        Set<ConstraintViolation<Clazz>> constraintViolations = validator.validate(clazz);
        System.out.println(constraintViolations.iterator().next().getMessage());
    }
}
kosmasd
  • 316
  • 1
  • 5