[hibernate-dev] [Bean Validation] Type-safe Validator and resolution algorithm

Emmanuel Bernard emmanuel at hibernate.org
Sun Jan 25 10:59:34 EST 2009


On  Jan 25, 2009, at 06:45, Sanne Grinovero wrote:

> The "check String length" "check Array size" and "check Collection
> size" validators could use different annotations;
> by the same criteria it would be fine for Collection, Map and Set to
> share the same annotation to check for
> size, as the implementation is only concerned about receiving a
> Collection as common superinterface.

So if we take the built-in constraints, we would have

@NotNull, @Null => ConstraintValidator<?, Object>
@AssertTrue, @AssertFAlse => ConstraintValidator<?, Boolean>  
(autoboxing)
@MinForNumber, @MaxForNumer => ConstraintValidator<?, Number>  
(autoboxing + BigDecimal and BigInteger)
@MinForString, @MaxForString => ConstraintValidator<?, String>
@SizeForCollection => ConstraintValidator<?, Collection>
@SizeForMap => ConstraintValidator<?, Map>
@SizeForArray => ConstraintValidator<?, Object[]>
@SizeForString => ConstraintValidator<?, String>
@DigitsForNumbers => ConstraintValidator<?, Number> (autoboxing +  
BigDecimal and BigInteger)
@DigitsForString  => ConstraintValidator<?, String>
@PastForDate => ConstraintValidator<?, Date>
@PastForCalendar => ConstraintValidator<?, Calendar>
@FutureForDate => ConstraintValidator<?, Date>
@FutureForCalendar => ConstraintValidator<?, Calendar>



And if for some reason we need to differenciate Bigdecimal/Integer  
from the other Number subclasses, we will need to do
@MaxForInteger
@MaxForShort
@MaxForLong
@MaxForFloat
@MaxForDouble
@MaxForBigInteger
@MaxForBigDecimal

Same when the new Date framework will show up, we will have another  
set of @Past* and @Future*

So instead of 10 primitive cosntraints, we end up with 18 up to 38+  
annotations

Are you *sure* you prefer the monotype with its proliferation of  
annotations to the multitype drawbacks?

>
>
> I can live with some more annotations if it is more explicit to
> understand which one is going to be used,
> especially if the validation framework warns me about incompatible
> types at startup.
> (and developers wouldn't need to consider mystic
> AmbiguousValidatorException implications).

No the Validation framework cannot warn you of incompatible types at  
startup because the list of bans is not known at startup. The  
exception will be raised when  
validator.validate(runtimeSpecificTypeInstance); is called and only if  
one of the getter values lead to inconsistency.
Your IDE or findbugs or whatever you use can help you (ie has the  
knowledge) but this is not enforced at compile time.

On ambiguity we can have three kind of rules:
  - raise an exception
  - choose the first validator matching in the constraint provider  
list the object instance type
  - choose the first validator matching in the constraint provider  
list the getter return type (ie the expected superset of the object  
instance type).

Note that if the constraint implementor is careful, this kind of  
ambiguity never happens:
  - String, Number, Date, Calendar combinations are never ambiguous
  - Object and any other type is never ambiguous

Things become ambiguous when you:
  - mix several "compatible" interfaces (ie interfaces that can be  
implemented by the same object and are not in the same hierarchy) eg.  
Serialuzable, Clonable
  - mix supertypes and interfaces (eg ArrayList and Serializable and  
if someone subclass ArrayList)




More information about the hibernate-dev mailing list