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

Gunnar Morling gunnar at hibernate.org
Wed Sep 4 04:50:23 EDT 2013


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

> On Wed 2013-09-04  9:26, Gunnar Morling wrote:
> > 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.
>
> What I am arguing then is that the getDeclaredType method is unnecessary if
> the converter class captures the type already via the From parameterized
> type.
>

To make this work you'd need to declare a converter class for each possible
wrapped type:

    StringUIInputConverter implements Converter<UIInput<String>> { ... }
    IntegerUIInputConverter implements Converter<UIInput<Integer>> { ... }
    ...

This may be feasible in some cases, but not e.g. for Optional<T> which
basically can take every type. In this case you'd want to parameterize the
implementation like this:

    class OptionalConverter implements Converter<Optional<?>> { ... }

Here you can't derive the wrapped type of a given element from the
converter class. But you can implement the required logic in a generic way
in getDeclaredType().


More information about the hibernate-dev mailing list