[bv-dev] Why do we need @MethodValidated anyways?
Emmanuel Bernard
emmanuel at hibernate.org
Thu Oct 11 15:30:17 EDT 2012
Following the overwhelmed silence, I went ahead and removed
`@MethodValidation`, clarify the interception logic and
add the alternative solution as a proposal
in the specification.
The pull request is https://github.com/beanvalidation/beanvalidation-spec/pull/15
Gunnar or Hardy will review the pull request before integrating it in
the specification proper.
Emmanuel
On Mon 2012-10-01 18:42, Emmanuel Bernard wrote:
> Hardy and I have discussed a possible solution to this problem.
>
> We remove @MethodValidated which does not seem to make much sense.
> We offer a contract (interface) in Bean Validation to select a given
> group(s) based on user provided code.
> We offer a programmatic (at configuration time) and XML way to disable
> method validation entire.
> We offer a contract (interface) in Bean Validation to enable or disable
> validation of a given method.
>
> interface MethodValidationGroupSelector {
> Class<?>[] selectGroupForMethod(Method method);
> //should we add some caller context?
> }
>
> interface MethodValidationActivator {
> Class<?>[] activateMethodValidation(Method method):
> //should we add some caller context?
> }
>
> Implementation of these objects would be dependency injectable objects
> like MessagetInterpolator, ConstraintValidator, etc.
>
> It seems that a way to access the caller would be useful to activate or
> not method validation but I don't know how to represent that. Maybe a
> simple call stack trace.
>
> An alternative solution that Hardy is sympathetic to is to not specify
> these contracts at all in Bean Validation and let the integration
> technology (say CDI) specify them. I think Bean Validation should take
> this responsibility though.
>
> I'd appreciate your feedback on this.
>
> Emmanuel
>
> On Fri 2012-09-28 18:19, Hardy Ferentschik wrote:
> > Hi,
> >
> > I already commented on Emmanuel's blog post - http://beanvalidation.org/news/2012/09/12/fine-control-over-method-validation, but
> > want to summarize on the mailing list as well.
> >
> > Bottom line is that I am also not convinced that @MethodValidated is needed.
> >
> > Let's talk about a the two main use cases this annotation is supposed to solve.
> >
> > #1 En- and disabling Method validation.
> >
> > Some of the responses on the post saw the use case of @MethodValidated in disabling method validation for classes/methods for performance reasons.
> > I am not sure, however, whether annotations is the best approach to do this. I think an external configuration (e.g. via xml) is in this case preferable.
> > The annotation approach is forcing people to recompile and redeploy their code which seems wrong in this use case and might not even be possible.
> >
> > Another important point is that this annotation does not work well when used in in hierarchies. To disable a method validation on a method of a subtype you have to
> > override the method in question to actually be able to place the annotation onto it. This will violate Liskov's substitution principle. This would not be valid:
> >
> > public class Foo {
> > public void placeOrder(@NotNull Order order) {
> > }
> > }
> >
> > public class Bar extends {
> > @MethodValidated(validationMode=NONE)
> > public void placeOrder(Order order) {
> > }
> > }
> >
> > @MethodValidated would only work on class level.
> >
> > #2 Specifying the validation group
> >
> > Again, annotations seem to be the wrong vehicle in this case. Really the groups to be validated should be determined
> > at the top level validateParameters/ReturnValue. To make this fully dynamic the user would need some sort of callback
> > to dynamically (based on some context information) determine the group to be validated. The callback would give the user
> > access method is validated on which instance. Based on this the user would return the group to be validated.
> > The question here is whether every integrator of method validation should provide its own interface/callback or whether
> > Bean Validation should specify it.
> >
> > Bottom line, I am backing up Emmanuel's concerns regarding the usefulness of @MethodValidated. I think the use cases people want
> > to use @MethodValidated it is not suitable and other options should be explored. Whether we need to specify these right now I am not sure
> > about.
> >
> > Hopefully this revives the discussion :-)
> >
> > --Hardy
> >
> >
> > On 12 Jan 2012, at 7:47 PM, Emmanuel Bernard wrote:
> >
> > > I am still working on the chapter describing how interceptor tech
> > > integrates bean validation. We have decided to convert most of the
> > > recommendations into mandatory rules. In particular around having method
> > > validation activated by default.
> > >
> > > Having a annotation to control whether or not a method was validated
> > > made sense when it was not enabled by default but I wonder if we still
> > > need it.
> > >
> > > I have a bunch of questions for you. I tried to keep them short and to
> > > the point so feel free to answer them one by one.
> > >
> > > ## What's your use case for disabling method validation?
> > >
> > > Why would you want to disable method validation on a given method or a
> > > given class?
> > >
> > > ## What's your use case for changing the default group?
> > >
> > > `@MethodValidated(groups=Heavy.class)` let's you change validation from
> > > the `Default` group to the group of your choice - in this case `Heavy`.
> > >
> > > Provided that we will offer support for group translation when cascading
> > > <http://beanvalidation.org/proposals/BVAL-208/>
> > >
> > > public class UserService {
> > > public void createUser(
> > > @NotEmpty @Email String email,
> > > @Valid @ConvertGroup(from=Default.class, to=BasicPostal.class)
> > > Address address ) {
> > > ...
> > > }
> > > }
> > >
> > > do we really need the ability do decide which group to use to validate a
> > > given method? What would be the use case?
> > >
> > > To me it seems that it could makes sense to validate one group over
> > > another based on:
> > >
> > > - some environmental consideration
> > > say a newbie user has more constraints on how it enters data
> > > than an advanced user hence different groups
> > > - the caller
> > > say a branch of the code wants to apply different rules than
> > > an other
> > >
> > > In both case, it does not make sense to define the group via an
> > > annotation on the method to be validated.
> > >
> > > This would need to be a rather container specific behavior to let people
> > > inject the right group for the right context.
> > >
> > > ## When would you want to only validate parameters or return values?
> > >
> > > `@MethodValidated.validationMode` let's you validate both method
> > > parameters as well as return value, or either one of them or none at all.
> > >
> > > Do you have a use case in mind for such need?
> > >
> > > ## What inheritance rules make sense for `@MethodValidated`?
> > >
> > > Assuming we have `@MethodValidated`, we need to define the overriding
> > > rules.
> > >
> > > We could decide that `@MethodValided` must be placed on the method to be
> > > validated (no overriding rule), or we could try and add some or all of
> > > the following rules:
> > >
> > > 1. `@MethodValidated` definitions on a method overrides the ones on a
> > > class
> > > 2. `@MethodValidated` definition on a subclass overrides the ones on
> > > superclasses
> > >
> > > Interfaces make things harder as there would be no magic rule to decide
> > > which definition has precedence over another in case of conflict.
> > > We could consider that methods of a class implementing an interface
> > > inherit the interface `@MethodValidated` definition (unless overridden).
> > > And in case two interfaces define the same method, overriding the
> > > `@MethodValidated` definition would be mandatory.
> > >
> > > I can live with rule 1, I can support rule 2. but I feel that the rules
> > > related to interfaces make things quite complex and not especially
> > > readable. Plus I don't see why you would want to add `@MethodValidated`
> > > on an interface. Not surprising as I don't see why one would do it on a
> > > class method anyways ;)
> > >
> > > ## Conclusion
> > >
> > > I realize that it must look like I am having a `@MethodValidated`
> > > mid-life crisis but better now than later :D
> > > _______________________________________________
> > > beanvalidation-dev mailing list
> > > beanvalidation-dev at lists.jboss.org
> > > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
> >
> >
> > _______________________________________________
> > beanvalidation-dev mailing list
> > beanvalidation-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
> _______________________________________________
> beanvalidation-dev mailing list
> beanvalidation-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
More information about the beanvalidation-dev
mailing list