[bv-dev] Updated proposal for container value extraction

Matt Benson mbenson at apache.org
Fri Jan 13 11:06:31 EST 2017


On Fri, Jan 13, 2017 at 2:04 AM, Emmanuel Bernard <emmanuel at hibernate.org>
wrote:

>
> 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.
>

Okay, you're right: List was a bad example, since its type parameter should
be a "plain" extractor. So let's use Optional, whose extractor is annotated
such that constraints apply to wrapped values by default:

@NotNull @ConstraintsApplyTo(ANNOTATED_ELEMENT) Optional<@NotNull
@ConstraintsApplyTo(ANNOTATED_ELEMENT) Optional<Foo>> optOptFoo;

This invokes question #2, whether there would be a way at the "top" level
to declare that neither the outer Optional nor the inner Optional may be
null. If so, the above example could be rewritten using that mechanism.

Matt


>
> @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=5)
> @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> {
>
>   @NotNull
>   T1 getT1();
>
>   @Min(3)
>   getSize();
>
>    ...
> }
>
> 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 ?
>
> _______________________________________________
> beanvalidation-dev mailing list
> beanvalidation-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20170113/740fc94d/attachment.html 


More information about the beanvalidation-dev mailing list