pirox22
pirox22

Reputation: 922

Different validations on same field based on active validation group

I am trying to validate a request object using Hibernate Validator.

As a simple example assume that the class of the object I am trying to validate has a B bObj field where B is another class that has a String name field .

For that reason, I have implemented my own custom Constraint Annotations linked to custom MyValidator implements ConstraintValidator classes.

DTO class

@AclassValidate(groups = {Operations.Insert.class, Operations.Update.class javax.validation.groups.Default.class})
public class A {

    @BclassValidate(groups = {Operations.Insert.class, Operations.Update.class})
    private B bObj;

    // setters, getters
}

My endpoint method signature (where validator gets invoked, and the active group is set):

@PostMapping("/test")
public A createA(
        @Validated(value = Operations.Insert.class) 
        // @Validated(value = Operations.Update.class) 
        @RequestBody A a
)

My validator class

public class BclassValidator implements ConstraintValidator<BclassValidate, B> {

    public void initialize(BclassValidate constraintAnnotation) {
    }

    public boolean isValid(B b, ConstraintValidatorContext constraintContext) {

        boolean valid = true;

        // Get active group here
        activeGroup = ..?
        if (activeGroup == Operations.Insert.class) {
            // check if b.getName() equals to "John"
        }
        else if (activeGroup == Operations.Update.class) {
            // check if b.getName() equals to "Doe"
        }

        return valid;
    }
}

What I want to achieve is to apply different validations for the same field based on the active group. The active group is the group, set at @Validated annotation. The question is how can I retrieve the active group in order to apply different validations based on its value?

Upvotes: 2

Views: 2817

Answers (3)

Kishor K
Kishor K

Reputation: 1635

Hibernate validator validating the currently active groups with the configured groups for custom constraints, so we no need to write logic to validate it. But there is no way to find the currently active groups.

Reason: 'valueContext' is holding the currently active group, but not passing to 'isValid' method.

https://github.com/hibernate/hibernate-validator/blob/master/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintTree.java

enter image description here

Upvotes: 0

fluminis
fluminis

Reputation: 4059

You should get the active validation groups like this:

public class BclassValidator implements ConstraintValidator<BclassValidate, B> {

    public void initialize(BclassValidate constraintAnnotation) {
    }

    public boolean isValid(B b, ConstraintValidatorContext constraintContext) {

        boolean valid = true;

        // Get active group here
        Set<Class<?>> activeGroups = null;
        if (context instanceof ConstraintValidatorContextImpl) {
            activeGroups = ((ConstraintValidatorContextImpl) context).getConstraintDescriptor().getGroups();
        } else {
            activeGroups = Collections.emptySet();
        }

        if (activeGroups.contains(Operations.Insert.class)) {
            // check if b.getName() equals to "John"
        }
        else if (activeGroups.contains(Operations.Update.class)) {
            // check if b.getName() equals to "Doe"
        }

        return valid;
    }
}

Upvotes: 0

Gunnar
Gunnar

Reputation: 18990

You cannot get hold of the currently validated group(s) from within a constraint validator.

Instead you should split up your constraint into several ones, in your case one for inserts and one for updates. Then you can assign these individual constraints to one validation group each.

Upvotes: 2

Related Questions