Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable field in a constraint annotation

I need to create a custom constraint annotation which can access the value of another field of my bean. I'll use this annotation to validate the field because it depends on the value of the other but the way I define it the compiler says "The value for annotation attribute" of my field "must be a constant expression".

I've defined it in this way:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=EqualsFieldValidator.class)
@Documented
public @interface EqualsField {
    public String field();

    String message() default "{com.myCom.annotations.EqualsField.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

public class EqualsFieldValidator implements ConstraintValidator<EqualsField, String>{

    private EqualsField equalsField;

    @Override
    public void initialize(EqualsField equalsField) {
        this.equalsField = equalsField;     
    }

    @Override
    public boolean isValid(String thisField, ConstraintValidatorContext arg1) {
        //my validation
    }

}

and in my bean I want something like this:

public class MyBean{

     private String field1;

     @EqualsField(field=field1)
     private String field2;
}

Is there any way to define the annotation so the field value can be a variable?

Thanks

like image 744
Javi Avatar asked Mar 18 '10 11:03

Javi


1 Answers

The easiest thing to do is take one step back: the constraint/validator you have written works on a field-level, but what you want to enforce is a cross-field dependency i.e. a class-level constraint.

Rewrite your constraint and validator to work at the class level (i.e. the annotation will go on the class, not on the field). That way you'll get access to the entire class. In your isValid(..) method, simply do a get on both the fields, compare, and return appropriately.

like image 119
GaryF Avatar answered Oct 10 '22 07:10

GaryF