12

I have a test like below:

public class TestSizeAnnotation
{
    public static void main(String[] args)
    {
        System.out.println(Validation.buildDefaultValidatorFactory().getValidator().validate(new C()));
    }

    public static class P
    {
        private List<String> lst = newArrayList("AA");
        @Size(max=0, message="P")
        public List<String> getLst()
        {
            return lst;
        }

        public void setLst(List<String> lst)
        {
            this.lst = lst;
        }
    }

    public static class C extends P
    {
        @Override
        @Size(max=5, message="C")
        public List<String> getLst()
        {
            return super.getLst();
        }
    }
}

with the following output:
[ConstraintViolationImpl{interpolatedMessage='P', propertyPath=lst, rootBeanClass=class com....validator.TestSizeAnnotation$C, messageTemplate='P'}]

However, I expected that the annotation can @Size be overridden, and no warning will appear.
Is there a way to accomplish that?

EDIT: I found a bug seems related to that, but I run 4.2.0 final and still get the above behavior.

Woodrow Barlow
  • 8,477
  • 3
  • 48
  • 86
oshai
  • 14,865
  • 26
  • 84
  • 140

3 Answers3

18

Overriding validation annotations is actually not supported for JSR-303. Instead annotations on overridden methods in the subclass will be applied cumulatively: From section 3.3 of the specification:

A constraint declaration can be placed on an interface. For a given class,
constraint declarations held on super- classes as well as interfaces are
evaluated by the Bean Validation provider. Rules are formally described in
Section 3.4.5.

The effect of constraint declarations is cumulative. Constraints declared
on a superclass getter will be validated along with any constraints defined
on an overridden version of the getter according to the Java Language
Specification visibility rules.
Perception
  • 79,279
  • 19
  • 185
  • 195
3

You can ovveride an annotation configured validation via xml configuration:

http://docs.jboss.org/hibernate/validator/4.2/reference/en-US/html_single/#validator-xmlconfiguration

In your case, if you declare a different validation (or no validation) for the getList() methid in the validation.xml file, it will override the @Size annotation.

Shivan Dragon
  • 15,004
  • 9
  • 62
  • 103
1

Just for the records, I have found a bypass for my problem:

public class TestSizeAnnotation
{
    public static void main(String[] args)
    {
        System.out.println("c " + 
                Validation.buildDefaultValidatorFactory().getValidator().validate(new C(), Default.class, SizeGroup2.class));
        System.out.println("p " + 
                Validation.buildDefaultValidatorFactory().getValidator().validate(new P(), Default.class, SizeGroup.class));
    }
    public static interface SizeGroup {}
    public static interface SizeGroup2 {}
    public static class P 
    {
        private List<String> lst = newArrayList("AA");
        @Size(max=0, message="P" , groups=SizeGroup.class)
        public List<String> getLst()
        {
            return lst;
        }
        public void setLst(List<String> lst)
        {
            this.lst = lst;
        }
    }
    public static class C extends P 
    {
        @Override
        @Size(max=5, message="C", groups=SizeGroup2.class)
        public List<String> getLst()
        {
            return super.getLst();
        }

    }
}
oshai
  • 14,865
  • 26
  • 84
  • 140
  • 3
    That's not an override, that's cumulative. In this case the initial validation will always pass if the second validation passes, but in other cases, where for example the initial validation is Min(...) and then you add Max(...) to the overriding method, you'll have it use both Min and Max validation (Max will not override the initial Min). – Shivan Dragon Dec 16 '12 at 21:30