I'm using JSR-303 validation (hibernate-validator) for an entity with a few different rules to be applied. Would rather not stack up multiple @Constraint
annotations for these and instead use a single one, e.g. @MyEntityConstraint
.
Problem is there really needs to be a different message for each type of validation failure but the message seems inextricably associated with the annotation:
public @interface MyEntityConstraint {
String message() default "A single, unchangeable message per constraint???";
// ...
}
Is there any way round this or am I doomed to have:
@MyEntityConstraint1
@MyEntityConstraint2
// ...
@MyEntityConstraintn
@Entity
public class MyEntity {
// ...
}
As suggested by Hardy, this can be done simply enough using ConstraintValidatorContext - as below:
@Override
public boolean isValid(MyEntity myEntity, ConstraintValidatorContext context) {
// Disable default ConstraintViolation so a customised message can be set instead.
context.disableDefaultConstraintViolation();
return checkConstraint1(myEntity, context)
&& checkConstraint2(myEntity, context)
//...
&& checkConstraintn(myEntity, context);
}
// Note: A private method for each constraint decreases the cyclomatic complexity.
private boolean checkConstraint1(MyEntity myEntity, ConstraintValidatorContext context) {
// Default validity is true until proven otherwise.
boolean valid = true;
if (/*<<Insert constraint #1 conditions (about myEntity) here>>*/) {
valid = false;
context.buildConstraintViolationWithTemplate(
"<<Insert constraint #1 failure message here>>").addConstraintViolation();
}
return valid;
}