Is it possible to access a field value, where field name is described in annotation which annotate another field in class.
For example:
@Entity
publi
You either need to write a class level constraint in which you get the full User instance passed into the isValid call or you can use something like @ScriptAssert.
At the moment it is not possible to access the root bean instance as part of a "normal" field validation. There is a BVAL issue - BVAL-237 - which discusses to add this functionality, but so far it is not yet part of the Bean Validation specification.
Note, there are good reasons why the root bean is not accessible atm. Constraints which rely on the root bean being accessible will fail for the validateValue case.
@Hardy Thenks for tip. Finally wrote some code which matches (more or less) expected result.
I'll paste it here, maybe will help someone to solve his problem.
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Match {
String field();
String message() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MatchValidator.class)
@Documented
public @interface EnableMatchConstraint {
String message() default "Fields must match!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class MatchValidator implements ConstraintValidator<EnableMatchConstraint, Object> {
@Override
public void initialize(final EnableMatchConstraint constraint) {}
@Override
public boolean isValid(final Object o, final ConstraintValidatorContext context) {
boolean result = true;
try {
String mainField, secondField, message;
Object firstObj, secondObj;
final Class<?> clazz = o.getClass();
final Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Match.class)) {
mainField = field.getName();
secondField = field.getAnnotation(Match.class).field();
message = field.getAnnotation(Match.class).message();
if (message == null || "".equals(message))
message = "Fields " + mainField + " and " + secondField + " must match!";
firstObj = BeanUtils.getProperty(o, mainField);
secondObj = BeanUtils.getProperty(o, secondField);
result = firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj);
if (!result) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addPropertyNode(mainField).addConstraintViolation();
break;
}
}
}
} catch (final Exception e) {
// ignore
//e.printStackTrace();
}
return result;
}
}
And how to use it...? Like this:
@Entity
@EnableMatchConstraint
public class User {
@NotBlank
private String password;
@Match(field = "password")
private String passwordConfirmation;
}