Using the Built-In Constraints to Make a New Constraint


#1

I’ve followed the example for Using the Built-In Constraints to Make a New Constraint in the Java EE Tutorial.

Since Email is a built-in, I switched it to USPhoneNumber, but very similar to the example annotating the USPhoneNumber with a @Pattern giving a regular expression for a phone number:

import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.Pattern;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Pattern(regexp = "\\+1-\\d{3}-\\d{3}-\\d{4}")
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@Documented
public @interface USPhoneNumber {
    String message() default "{com.XYZ.validation.USPhoneNumber.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

I then applied the @USPhoneNumber to a bean field and tested. What surprised me is that when a phone number doesn’t match the regular expression, I do not get a USPhoneNumber violation, instead I get a Pattern violation.

ConstraintViolationImpl{interpolatedMessage=‘must match “+1-\d{3}-\d{3}-\d{4}”’, propertyPath=phoneNumber, rootBeanClass=class com.XYZ.bean.PersonBean, messageTemplate=’{javax.validation.constraints.Pattern.message}’}

I really think the constraint violation should be the USPhoneNumber with its associated message.
Anything I’ve done wrong here that’s preventing me from seeing a USPhoneNumber violation, or is this the way its supposed to work?

IMHO, what would be ideal is if this were handled analogous to nested exceptions, where I would get a USPhoneNumber violation caused by a Pattern violation.


#2

@ReportAsSingleViolation is what you are looking for.

Just add it on your constraint and it will report only the violation of the composed constraint as soon as one of the composing constraint is violated.


#3

It works, exactly what I was looking for. Thank you.