Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSR 303 Custom constraint Override

i want to put set of standart constraints (like not null alphanumeric string with length from 3 to 240 chars) on the fields (String in this case) and want to know is there a way to override some of this constraint in the model code. Also is this will be an overriding, or just validating two times for overrided annotation?

it should be something like this

@AlphanumericString
@Size(min=100, max=150) //override standart values from AlphanumericString annotation

thanks for you answers

ok, answer myself. there is @OverridesParameter wich helps to reassign nested annotation parameter

@Numerical
@Size //arbitrary parameter values
@ConstraintValidator(FrenchZipcodeValidator.class)
@Documented
@Target({ANNOTATION_TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface FrenchZipCode {
    String message() default "Wrong zipcode";
    String[] groups() default {};

    @OverridesParameters( {
        @OverridesParameter(constraint=Size.class, parameter="min")
        @OverridesParameter(constraint=Size.class, parameter="max") } )
    int size() default 5;

    @OverridesParameter(constraint=Size.class, parameter="message")
    String sizeMessage() default "{error.zipcode.size}";

    @OverridesParameter(constraint=Numerical.class, parameter="message")
    String numericalMessage() default "{error.zipcode.numerical}";
}

source

like image 219
Andrey Avatar asked Dec 06 '11 06:12

Andrey


1 Answers

It's a nice question. The JSR 303 Bean Validation specification describes validation routine in the section 3.5.

For a given group to validate, the validation routine applied on a given bean instance is expected to execute the following constraint validations in no particular order:

  • for all reachable fields, execute all field level validations (including the ones expressed on superclasses) matching the targeted group unless the given validation constraint has already been processed during this validation routine for a given navigation path (see Section 3.5.1) as part of a previous group match.

...

The object validation routine is described as such. For each constraint declaration:

  • determine for the constraint declaration, the appropriate ConstraintValidator to use (see Section 3.5.3).
  • execute the isValid operation (from the constraint validation implementation) on the appropriate data (see Section 2.4)
  • if isValid returns true, continue to the next constraint,
  • if isValid returns false, the Bean Validation provider populates ConstraintViolation object(s) according to the rules defined in Section 2.4 and appends these objects to the list of constraint violations.

In your case, you deal with validation of a simple String field where the targeted group is Default. You have two validation constraints (@AlphanumericString and @Size) which according to the documentation will be validated/processed separately in no particular order.

So to answer your question. No, there will be no override applied to your @AlphanumericString when you use @Size additionaly. To be able to achieve what I think you attempt to do, you may create a constraint composition where you overridde attributes from composing annotations like that:

@Pattern(regexp="[a-zA-Z]*")
@Size
@Constraint(validatedBy = AlphanumericStringValidator.class)
@Documented
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface AlphanumericString {
   // ...
  @OverridesAttribute(constraint=Size.class, name="min")
  int min() default 3
  @OverridesAttribute(constraint=Size.class, name="max")
  int max() default 230;       
   // ...
}

and use it like that:

@AlphanumericString(min = 100, max = 150)
like image 55
nowaq Avatar answered Sep 25 '22 01:09

nowaq