[bv-dev] Constructor validation

Emmanuel Bernard emmanuel at hibernate.org
Mon Dec 5 05:46:32 EST 2011


On 4 déc. 2011, at 16:50, Gunnar Morling wrote:

>> 
>> - inheritance: you pass a java.lang.Method object of class A to
>> validateMethodParameters() and an object of class B extending class A
>> which overrides this method. Which constraints are checked, the ones of
>> the method declared on class A, the ones declared on the method of class
>> B or the sum of the methods in A & B?
> 
> That's a very good question.
> 
> In fact in Hibernate Validator we don't support parameter constraints
> in overriding methods at all (so if A#foo() has parameter constraints,
> B#foo() must not declare any parameter constraints), as this
> represents a strengthening of preconditions in sub-types for clients
> of A, which violates the Liskov substitution principle. Some more
> reasoning can be found in the HV reference guide in section 8.3.1.1
> [1].
> 
> I'm preferring this approach, though it is rather conservate. Some
> "programming by contract" solutions deal with this by OR-ing the
> preconditions in a method's hierarchy (so an invocation would be
> valid, if the constraints at A#foo() OR B#foo() are satisfied),
> actually applying the "weakest" contract in the hierarchy. How is this
> done in OVal? And does anyone know how it is in Apache BVAL?

Note that return type constraints could be refined theoretically and be compliant with the Liskov substitution principle. We might want to still disallow this to limit confusion. It will all depend on the set of use case we can think of.

> 
>> - When you add a method return value constraint to a parameterized
>> method and you do Validator.validate(object), thoses constraints are not
>> evaluated. But when you add a constraint to a getter-style method (which
>> also looks and actually is a method return value constraint). They are
>> evaluated by Validator.validate(object). What if someone wants to add a
>> method return value constraint to a getter-style method, that is not
>> evaluated when Validator.validate(object) is executed but after the
>> method itself has been invoked? In OVal you have to explicitely add the
>> @IsInvariant annotation to getter methods if their constraints should be
>> evaluated too when Validator.validate(object) is executed. If so, OVal
>> will invoke the getter and test the returned value against the
>> constraints specified.
> 
> Personally I'd say getters are methods such as any other methods, too.
> So if a getter method is invoked one some bean generally qualifying
> for method validation (however that is decided by the method
> validation integration layer) the method's constraints should be
> validated in the same way as any other method constraints. If the bean
> is validated using Validator#validate(), the getter method's
> constraints should be handled as property constraints as it's the case
> today IMO.

@IsInvariant is not much different from a group (though a bit more elegant). I don't think we should add something explicit in the spec to address this problem as we already can solve it with groups.
Note that getters are not like ordinary methods, they are (by convention) Java properties and that's exactly what validator.validate processes (properties).


More information about the beanvalidation-dev mailing list