[hibernate-dev] [Validator] Applying constraints to property objects

Gunnar Morling gunnar at hibernate.org
Wed Sep 4 03:26:07 EDT 2013


2013/9/4 Emmanuel Bernard <emmanuel at hibernate.org>

> On Wed 2013-09-04  8:27, Gunnar Morling wrote:
> > 2013/9/3 Emmanuel Bernard <emmanuel at hibernate.org>
> >
> > > Something like c makes sense.
> > >
> >
> > Ok.
> >
> >
> > > It similar to the notion of converter in JPA.
> > >
> > > But why not the following style of interfaces
> > >
> > >     interface Convert<From,To> {
> > >         To convert(From);
> > >     }
> > >
> >
> > Yes, thinking more about it, it probably makes sense to support multiple
> > converters, e.g. in case someone works with UIInput and *Property in the
> > same application. Then the "From" parameter makes sense to avoid casts
> > within the converter implementation. Need to experiment with it a bit.
>
> More than just the cast in the impl, its a way to statically know that
> you have a converter that takes From and only From, so you can restrict
> the list of converters to consider to 0 or 1 all the time (assuming we
> don't support multiple converters of the same From.
>
> >
> > Regarding the name, I find "Converter" a bit too generic, in particular
> > since it needs not only to convert the actual property value but also the
> > static type so you can reject this (because @Size can't be applied to
> > Object):
>
> Not sure I follow, before the core HV work, it converts a property or
> class from From to To and from there you are good to go.
>
> Are you saying that if From = UIInput<String> we would not be able to
> separate it from UIInput<Object> statically? I *think* we can, just like
> we do for collections in JPA.
>

No, I'm not saying that. I also think we can separate that.

There is two steps involved:

* Resolve the correct validator for the validated element, using its
declared (static) type; E.g. in the following case we'd need to find the
validator for @Size/String:

    @Size(min=3)
    UIInput<String> name;

While in this case we'd have to throw an exception since there is no
validator for @Size/Object:

    @Size(min=3)
    UIInput<Object> name;

For this step I envisioned the method "Type getDeclaredType(Type
sourceType)" (better name to be found, unwrapDeclaredType()?), which would
return the "real" type to consider for validator resolution (here, String
or Object, respectively).

* If we have found the right validator, use it to validate the given value.
For this step I envisioned the getValidatedValue() method which obtains the
value from the given wrapped property before passing it to the validator.

--Gunnar


>
> >
> >     @Size(min=3, max=10)
> >     UIInput<Object> name;
> >
> >
> > On Tue 2013-09-03 15:58, Gunnar Morling wrote:
> > > > Hi,
> > > >
> > > > Yesterday George Gastaldi from the Forge team approached me
> regarding the
> > > > application of constraints to "wrapped" properties. Their situation
> is
> > > the
> > > > following:
> > > >
> > > >     ...
> > > >     @Size(min=3, max=10)
> > > >     UIInput<String> name;
> > > >     ...
> > > >
> > > > Here, UInput is some kind of UI component, wrapping the actual
> property
> > > > value. As is, validation of this property will fail since there is no
> > > > validator for applying @Size to UIInput (only for String).
> > > >
> > > > A similar use case exists in JavaFX where one might want to apply
> > > > constraints to the FX *Property types:
> > > >
> > > >     ...
> > > >     @Min(5)
> > > >     IntegerProperty count = new SimpleIntegerProperty(4);
> > > >     ...
> > > >
> > > > Again, validation will fail out of the box, as no validator for
> applying
> > > > @Min to IntegerProperty exists (but for int/Integer).
> > > >
> > > > How could this be solved? The following alternatives came to my mind:
> > > >
> > > > a) Create and register validators for these wrapper types, e.g.
> > > > ConstraintValidator<Size, UIInput> etc.
> > > >
> > > > Pro: Works with the existing APIs without modification
> > > > Con: Lots of code to write, either duplicating code or delegating to
> > > > (internal) implementation types; doesn't automatically benefit from
> new
> > > > built-in validators
> > > >
> > > > b) Apply constraints to getters instead of fields:
> > > >
> > > >     IntegerProperty count = new SimpleIntegerProperty(4);
> > > >
> > > >     @Min(5)
> > > >     int getCount() {
> > > >         return count.getValue();
> > > >     }
> > > >
> > > > Pro: Works with the existing APIs without modification; benefits
> from any
> > > > newly added built-in validators
> > > > Con: There may be cases where there is no such getter, e.g. for
> parameter
> > > > validation
> > > >
> > > > c) Provide an SPI which allows to plug in a custom "value processor"
> > > > implementation, retrieving the wrapped object and its "declared"
> type:
> > > >
> > > >     public interface ValidationValueProcessor {
> > > >         Object getValidatedValue(Object source);
> > > >         Type getDeclaredType(Type sourceType);
> > > >     }
> > > >
> > > > For the original example, the methods would return the name value and
> > > > String.class, respectively.
> > > >
> > > > Note that validator resolution is done using the static type of a
> > > property,
> > > > so I think the original example above should be supported, but the
> > > > following should not as no validator for @Size/Object exists:
> > > >
> > > >     @Size(min=3, max=10)
> > > >     UIInput<Object> name;
> > > >
> > > > Pro: Benefits from any newly added built-in validators, allows
> directly
> > > > annotating "wrapped" properties, requires no implementation by the
> user
> > > > besides the ValidationValueProcessor
> > > > Con: new HV-specific (at least for the time being) SPI
> > > >
> > > > I think a) creates prohibitively high efforts for the
> user/integrator, b)
> > > > lacks support for method constraints, so I think c) should be
> > > implemented,
> > > > possibly making this a spec SPI later on.
> > > >
> > > > Does anyone have other preferences or alternatives? If you also
> think c)
> > > > makes most sense, do you have a good/better idea for the interface
> and
> > > > method names?
> > > >
> > > > Thanks,
> > > >
> > > > --Gunnar
> > > > _______________________________________________
> > > > hibernate-dev mailing list
> > > > hibernate-dev at lists.jboss.org
> > > > https://lists.jboss.org/mailman/listinfo/hibernate-dev
> > >
>


More information about the hibernate-dev mailing list