1

I am in need to call validator.validateProperty() from my custom Validator and looking for a way to pass BOTH messageTemplate and interpolated message to ConstraintValidatorContext. What i want to achieve is that if given property has a particular value than fire validation of another property.

MyCustomClassLevelValidator implements ConstraintValidator<Foo, Bar>{
@Autowired
private Validator validator
 public boolean isValid(Bar bar,
        ConstraintValidatorContext constraintValidatorContext){
    if(bar.isSth()){
      Set<ConstraintViolation<Bar>> somePropViolations = validator.validateProperty(bar, "someprop", Conditional.class);
      for (ConstraintViolation<Bar> propertyViolation : somePropViolations) {
         constraintValidatorContext.disableDefaultConstraintViolation();
         constraintValidatorContext.buildConstraintViolationWithTemplate(propertyViolation.getMessageTemplate()).addNode(propertyViolation.getPropertyPath().toString())
            .addConstraintViolation();
   }   
    }
 }
} 

So the problem with my code is that when Bar is validated, constraint violations on "someprop" are not fully interpolated (constraint annotations attributes are not resolved)

class Bar{
  ...
  @Digits(groups=Conditional.class, integer=4,fraction=0)
  String someProp;
}

So when validating Bar like

Bar bar = new Bar();
bar.setSomeProp("99.9");
Set<ConstraintViolation<Bar>> constraintViolations = validator.validate(bar); 

i see numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected) instead of numeric value out of bounds (<4 digits>.<0 digits> expected)

Is there any way i put BOTH message Template and message text (interpolated version) on constraintValidatorContext ?

1 Answer 1

1

I don't think it's a good idea to call back to Validator from within a constraint validator implementation, as this might easily cause endless loops when validating the same object again, which hosts the current object.

Depending on how you invoke validation, you could you simply pass the Conditional group to the validation call:

if(bar.isSth()) {
    Set<ConstraintViolation<Bar>> constraintViolations = 
        validator.validate(bar, Conditional.class);
}
else {
    Set<ConstraintViolation<Bar>> constraintViolations =
        validator.validate(bar);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Hi Gunnar this is what i finally ended up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.