Creating a simple constraint - The ConstraintValidatorContext
3.1.2.1. The ConstraintValidatorContext Example 3.3, “Implementing a constraint validator for the constraint CheckCase” relies on the default error message generation by just returning true or false from the isValid call. Using the passed ConstraintValidatorContext object it is possible to either add additional error messages or completely disable the default error message generation and solely define custom error messages. The ConstraintValidatorContext API is modeled as fluent interface and is best demonstrated with an example: Example 3.4. Use of ConstraintValidatorContext to define custom error messages package com.mycompany; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class CheckCaseValidator implements ConstraintValidator { private CaseMode caseMode; public void initialize(CheckCase constraintAnnotation) { this.caseMode = constraintAnnotation.value(); } public boolean isValid(String object, ConstraintValidatorContext constraintContext) { if (object == null) return true; boolean isValid; if (caseMode == CaseMode.UPPER) { isValid = object.equals(object.toUpperCase()); } else { isValid = object.equals(object.toLowerCase()); } if(!isValid) { constraintContext.disableDefaultConstraintViolation(); constraintContext.buildConstraintViolationWithTemplate( "{com.mycompany.constraints.CheckCase.message}" ).addConstraintViolation(); } return result; } } Example 3.4, “Use of ConstraintValidatorContext to define custom error messages” shows how you can disable the default error message generation and add a custom error message using a specified message template. In this example the use of the ConstraintValidatorContext results in the same error message as the default error message generation. Tip It is important to end each new constraint violation with addConstraintViolation. Only after that the new constraint violation will be created. In case you are implementing a ConstraintValidator a class level constraint it is also possible to adjust set the property path for the created constraint violations. This is important for the case where you validate multiple properties of the class or even traverse the object graph. A custom property path creation could look like Example 3.5, “Adding new ConstraintViolation with custom property path”. Example 3.5. Adding new ConstraintViolation with custom property path public boolean isValid(Group group, ConstraintValidatorContext constraintValidatorContext) { boolean isValid = false; ... if(!isValid) { constraintValidatorContext .buildConstraintViolationWithTemplate( "{my.custom.template}" ) .addNode( "myProperty" ).addConstraintViolation(); } return isValid; }