[bv-dev] Updated proposal for container value extraction

Emmanuel Bernard emmanuel at hibernate.org
Fri Jan 13 03:04:57 EST 2017

> On 12 Jan 2017, at 19:45, Matt Benson <mbenson at apache.org> wrote:
> > 2. Should @ConstraintsApplyTo be usable per-constraint?
> >   Doing such seems like it could be a bit clumsy, but it might be okay if @ConstraintsApplyTo were repeatable and included Class<? extends Annotation>[] constraintTypes() default {} element which, if non-empty, could differentiate which constraints applied to the wrapper vs. the extracted value.
> Do you mean?
> @ConstraintAppliesTo(target=WRAPPED_VALUE, constraintTypes=Min.class)
> @Min(3)
> List<String> nicknames;
> This approach cannot cover a case were the Min constraint it used one for the container and one for the wrapped value.
> That is what I was postulating, yes. Min might not be the best example. NotNull might be a better example of a constraint that one would want to apply both to the wrapper and the extracted value.

In this case, let’s use @Size whbich would make the example valid.  A list of at least 3 elements vs a nickname of at least 3 characters.

> But it makes me think that we sorta addresssed a similar class of problem with groups.
> I haven’t explored at all but could we something similar by subverting groups. Let’s define two special groups: OnContainer OnWrappedValue
> @Min(value3, groups=OnWrappedValue.class)
> List<String> nicknames;
> // note that these examples are simplifications and should really be written List<@Min String> nicknames;
> // but pretend we have a subclass of List<String> with no way to put a TYPE_USE constraint
> The idea is kind of cute (for lack of a better word), but doesn't this complicate or prevent "normal" use of validation groups?

Right, it needs to be explored enough to qualify or be rejected.
I * think* that since groups are additive in nature and if we disallow people to use these special groups in sequences and other groups, they would not interfere at all.

> This proposal would not address the case of multiple nestsed containers List<List<String>>
> I agree that specifying WRAPPED_VALUE per-property is ambiguous for List<List<String>>. Maybe that is an argument against allowing #8. What if the rule were that @ConstraintsApplyTo(WRAPPED_VALUE) is valid on TypeExtractor class definitions, while @ConstraintsApplyTo(ANNOTATED_ELEMENT) is valid elsewhere, serving only to override the behavior specified by the extractor? Then you could have @Size(min=5) @ConstraintsApplyTo(ANNOTATED_ELEMENT) List<@Size(min=3) @ConstraintsApplyTo(ANNOTATED_ELEMENT) List<String>> . This still doesn't solve #2, but I think the problems are orthogonal.

I suppose this assumes that most if not all extractor would have @ConstraintsApplyTo(WRAPPED_VALUE) set so that a user has the option to do annotated element vs wrapped value on site. That would be a bad default for iterable and break BV 1.1 semantic in a backward incompatible way (without @ConstraintsApplyTo on site, my @Min annotation would not longer validate the container size but what’s inside.

Plus the example you give is just bad practice and illogical to quote Spok.

@Size(min=5) @ConstraintsApplyTo(ANNOTATED_ELEMENT) List<@Size(min=3) @ConstraintsApplyTo(ANNOTATED_ELEMENT) List<String>>

If you can plance constraints where you want, place then where they are the more natural and in this case the example is rewritten

@Size(min=5) List<@Size(min=3) List<@Size(min=3) String>>

The problema rises when you have class Matrix extends List<List<String>> {}
You have no place to put @Size(min=3) and @Size(min=24)

@Size(min=3) //I want to be in the inner list
@Size(min=24) // I want to be in the most inner wrapped element
Matrix matrix;

TODO: I think I’m fine with not supporting such case and support #8 personally.

> > 7. Should the presence of type argument constraints alone trigger nested validation?
> >   I can appreciate the sense of the consistency argument to requiring @Valid, but in practice it seems reasonable to me that @Valid be implied. It probably would be much simpler to require @Valid from an implementation perspective, however.
> I personally am a bit reluctant. Do we really think that this is the default behavior people will want? Because you cannot negate a @Valid today so that’s a definitive decision. It seems to be that many containers are not beans per se and don’t want their properties to be validated, just the extacted stuff,.
> Are you saying that type argument constraints will be validated using extraction, but that only validation of the Map object *itself* would depend on @Valid to trigger validation of Map values per BV 1.x? So if Address had validation metadata, you could have:
> Map<AddressType, @NotNull Address>
> And BV would validate that the values were non-null, but would not invoke Address validation without @Valid on the Map (BV 1.x) or on the Address type parameter? That makes sense to me. You could then combine:
> Map<AddressType, @NotNull @Valid Address>

Your understanding is correct, to validate the properties of Address, you need the @Valid annotation.

What the question 7 is about though is a bit different, I think (I’m confused now too :) )

Assume the following container class

class Tuple<T1,T2> {

  T1 getT1();


Does the following validate that Integer is not null, does it validate that tuple size is at least 3?

Tuple<@Min(1) Integer, @Email String> tuple;

Is that a fair understanding of the question Gunnar ?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20170113/69c88f55/attachment-0001.html 

More information about the beanvalidation-dev mailing list