JSR 303 Bean Validation - Why on getter and not setter?
Asked Answered
T

4

41

I don't understand why JSR 303 (bean validation) is for the getter methods and not setter? Isn't it more logical to put it under setter method since that is the entry point into a field and validation should be checked prior to that?

Turkoman answered 8/6, 2011 at 18:52 Comment(4)
I don't understand why you're putting the constraint on a getter instead of the field itself. Isn't it more logical to put it on the field itself since that is, well, the sole field itself?Guereza
@Guereza Yeap! I agree with you. So the question is if i do validation on that one field, do i also need to put annotation on that field getter method? If not, why is there annotation at all for the getter method?Turkoman
You should definitely not put it in both places. It will cause the field to be validated twice, according to the Hibernate docs.Chamberlain
Same question, putting on setter or field itself is more intuitive. Some libraries used it in the wrong place, and now I can't load those libraries because of the validation exceptionMensa
U
41

Annotating getters doesn't mean that validation is performed when a getter is invoked. It is just used to identify the property to which a constraint shall apply.

The big advantage of putting constraints on (usually public) getters instead on (typically private) fields is that the constraints are part of the type's public API that way. They will even be added to the generated JavaDoc. A user of a type knows that way which constraints apply to it without looking into its internal implementation.

Another advantage of annotating getters is that constraints can be put at methods on base classes or interfaces and also apply for any sub-types/implementations.

Underwood answered 8/6, 2011 at 21:27 Comment(3)
If that is the case, i don't see any issue if the constraints being put on the public setter method. Same outcome as per your answerTurkoman
I think one advantage of using getter instead of setter methods is that this allows to have immutable properties for which no setter exists while getting the advantages of property level (oposed to field level) constraints as outlined above.Underwood
@Turkoman please take a look at my answer. There is a problem with setter method. You can not always predict right field using public setter method.Tennant
L
8

Its a very good question and something that I have never paid attention to. But I think I know the answer ( and also why I never got this question myself).

If you are looking at this, from the point of view that, the annotation defines where the validation will happen, then putting it on getter does not make sense. ( why not validate while storing the value itself..). But this is not how it works...

The programmer needs to tell the validation framework, which properties needs to be validated. So you can put the annotation directly on the attribute (which I prefer) or you can put it on the getter. Both of them signify read operation. The Framework needs to read all the attributes of your class, that will have to be validated. So in this case, putting on setter makes no sense at all.. The key to understand is the perspective...

I hope it makes sense.

Lobster answered 8/6, 2011 at 19:13 Comment(3)
Yes, it wont make sense if you look at it that way. I do not think positioning your annotation on getter, performs the validation on getter. We are just marking that attribute as something the framework needs to validate.Lobster
i understand what you are trying to say. As far as i understand regarding the JSF life cycle, if there is a validation error during the Process Validation phase, the same page is redisplayed. Shouldn't a setter method be invoked to do validation? A getter method is only invoked upon a page rendering phase. Why do validation on a page rendering phase? The way i look it, it's pointless to do validation in this phase since .. well all is good now and hence the said page is rendered for display.Turkoman
Its because there are cases where there is no setter method. The setter would not be included say on a read only property.Inaccessible
A
5

Consider this code:

public class BeanValidation {

    private int nameSetCount = 0;
    private int nameGetCount = 0;
    private String name;

    public String getName() {
        this.nameGetCount++;
        return name;
    }

    public void setName(String name) {
        this.nameSetCount++;
        this.name = name;
    }

}

Put annotation over private String name;

Annotation identifies field easily just looking at the field.

Put annotation over public String getName()

Annotation identifies field easily just looking at the returned field.

Put annotation over public void setName(String name)

Annotation can not identify field looking at the modified field because there can be more than one.

Arthur answered 10/6, 2011 at 19:52 Comment(1)
reflection doesn't look at the method implementation, it looks at the name of the getter/setter and matches that up to a fieldAcceptor
C
1

Bean Validation is called that way for a reason. It is applied to an initialized bean. So, first off, you initialize it with everything you have, then you pass it(or it is passed explicitly) to the Bean Validation implementation, which will rely on the validation annotations when accessing the fields. In case of Spring MVC validation handling starts at:

result = execVal.validateParameters(
                invocation.getThis(), methodToValidate, invocation.getArguments(), groups);

inside MethodValidationInterceptor. From here on, it's passed to validation implementation, in most cases Hibernate. invocation.getArguments() will contain all the method arguments already initialized with the given values, regardless of validation annotations.

Chamberlain answered 11/2, 2019 at 12:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.