Ordered Validation (practically)
by Cemo
Hi experts,
After reading your comments and mail list I realized that it will be better
share our opinions here about our problems.
First, I would like to thanks all of you to provide such an elegant library
and spec. After latest improvements at spring side, I am sure that bean
validation will be defacto validation framework among java community.
The only problem We are facing is that ordered validations.
In a common sense validation such this can be feasible:
public class AccountBean {
>
> @CheapValidation(groups=Name1.class)
> @ExpensiveValidation(groups=Name2.class)
> @VeryExpensiveValidation(groups=Name3.class)
> String name;
>
> @CheapValidation(groups=Surname1.class)
> @ExpensiveValidation(groups=Surname2.class)
> @VeryExpensiveValidation(groups=Surname3.class)
> String surname;
>
> public interface Name1 {}
> public interface Name2 {}
> public interface Name3 {}
> @GroupSequence({Name1.class, Name2.class, Name3.class})
> public interface Name {}
>
> public interface Surname1 {}
> public interface Surname2 {}
> public interface Surname3 {}
> @GroupSequence({Surname1.class, Surname2.class, Surname3.class})
> public interface Surname {}
> }
>
>
There is two common usage for this. The first usage: some validations are
expensive that should be runned if all validations pass. Another usage is
for each field there should be one violation. For email, if it is empty,
uniqueEmail constraint must not be checked. I hope that how much necessary
it is for us you can imagine. Almost all fields has such restrictions.
Ordering and shortcutting are crucial for us.
But just to provide validation order and shortcut GroupSequence is
practically impossible to use at enterprice level. For each field again
and again we are declaring interfaces. It is not only intuitive but also
seems ugly. By the way what is came to my mind is for each constraint,
declaring a order like this:
public class AccountBean {
>
> @CheapValidation(order=0,groups=Name1.class)
> @ExpensiveValidation(order=1,groups=Name2.class)
> @VeryExpensiveValidation(order=2,groups=Name3.class)
> String name;
>
> @CheapValidation(order=0,groups=Surname1.class)
> @ExpensiveValidation(order=1,groups=Surname2.class)
> @VeryExpensiveValidation(order=2,groups=Surname3.class)
> String surname;
> }
>
>
Default value for ordering might be same for all constraints.
Please help community. :)
Thanks & happy new year
12 years, 11 months
MessageSource for ReportAsSingleViolation
by Cemo
Hi,
After having great comments and motivation from your comments, I would like
to share another idea in before filing an issue.
Composing a new constrain based on other constraints are frequently used in
our production systems. However sometimes I was desperately desiring an
option to display message by violating constraint. It can be considered
this option as complementary option for ordered constraints. Ordered
constraints are discussed at another topic but for composite constraints It
can be great to option select message source. Parent (composer) or child
(composed) message source.
@ReportAsSingleViolation(messageSource= COMPOSER)
I believe that flexibility to select message to display is great.
What are your opinions?
Thanks
12 years, 11 months
Re: [bv-dev] Ordered Validation (practically)
by Cemo
Hi,
Emmanuel, I can really see your points about ordering numbers (the salience
approach). I think that you are totally right. But in terms of usability
declaring again and again interfaces are killing usability. At your example
there is a still need for declaring them. And also at the order of the
constraints are can not be reached by reflection.
At this point I believe that defining order explicitly is the best. Maybe
like GroupSequence we can use ConstraintSequence whose target type "Field,
Method, Type" as opposite to GroupSequence whose target type "Type".
GroupSequence implies group related operations as expected, whereas
ConstraintSequence implies ConstraintSequence. For me really it makes sense.
For my use case I just want to not declaring again and again interfaces.
For M class and N field I have to declare (M) x (N) x (Annotation Count)
Interface. And without declaring interface I would like to have short
circuit feature.
Thanks
But there is another point too. Groups are used also for partial
validation. And groups are really implies this partial validation with its
name very good.
On 4 January 2012 16:29, <beanvalidation-dev-request(a)lists.jboss.org> wrote:
> Message: 3
> Date: Wed, 4 Jan 2012 15:25:10 +0100
> From: Emmanuel Bernard <emmanuel(a)hibernate.org>
> Subject: Re: [bv-dev] Ordered Validation (practically)
> To: beanvalidation-dev List <beanvalidation-dev(a)lists.jboss.org>
> Message-ID: <9B5F338F-1682-438B-8270-A2A0E9DADE81(a)hibernate.org>
> Content-Type: text/plain; charset=us-ascii
>
> I have what I think is a nice solution for BVAL-248 and for the uses case
> Cemo has
>
> The issue in this case is that you want the logic of group sequence but
> only per target (property, class, annotation).
>
> We can dot he following for that reusing HV-462's example
>
> ```
> interface Cheap {}
> interface Expensive {}
>
> @GroupSequence(value={Cheap.class,Expensive.class}, ordering=PER_TARGET)
> public class DomainObject {
>
> @Size(max=50, groups=Cheap.class) // constraint 1a
> @Pattern(regexp="[a-z]*", groups=Expensive.class) // constraint 1b
> private String name;
>
> @Size(max=20, groups=Cheap.class) // constraint 2a
> @URL(groups=Expensive.class) // constraint 2b
> private String email;
>
> @Size(max=100, groups=Cheap.class) // constraint 3a
> @Pattern(regexp="[0-9]*", groups=Expensive.class) // constraint 3b
> private String password;
> }
> ```
>
> The default @GroupSequence.ordering would be GLOBAL which is the current
> behavior.
>
> This solution is not technically as orthogonal than a true salience model
> but would that work for the use cases you have in mind?
>
> We can apply the same kind of solution on @ReportAsSingleViolation
>
> What do you think?
>
> Emmanuel
>
12 years, 11 months
Re: [bv-dev] Ordered Validation (practically)
by Gunnar Morling
Hi,
welcome to the list.
> "When @ReportAsSingleViolation is present, short circuit."
I think the problem here is that this approach relies on the order of
constraint annotations as specified in the source code. AFAIK there is no
way to retrieve annotations which would garuantee this order.
Another question would be how constraints from different sources
(annotation, XML) would be ordered.
--Gunnar
Am 04.01.2012 07:37 schrieb "Peter Davis" <davispw(a)gmail.com>:
12 years, 11 months
Re: [bv-dev] Ordered Validation (practically)
by Cemo
Hi,
Exactly. I would like to return only one failure per property in an ordered
way. Let me to summaries a few more use cases (skipping empty,null
constraints):
- In order to validate credit card we have more than 3 constraints.
1. CardNumberValidator (Is it randomly entered or not?),
2. BlackListValidator (Is this blacklisted?)
3. BankValidator (Is Bank lets us to use it?)
- Our users can change their location up to a count (2 times in 3 months)
1. LegalCityValidator (Is there really such a city)
2. LocationChangerValidator (Is location changeble? Users can not
change their city very often.)
- Our email validations are extensive because of the nature our products.
1. LegalEmailChecking (Thanks to Hibernate)
2. BlackListEmailValidator
3. ForbiddenEmailValidator (Some of are users using forbidden
keywords such as domain names in their emails.)
ReportAsSingleViolation is totally different than what we need by the way.
It is also very useful but in terms of compositing new constraints. It can
not let us to choose which constraint is violated and thus we can not
display appropriated error message. The current spec is really addressing
very well known issues such as partial validation, composite constraints
but its usefulness for ordering is really questionable.
I am really suffering lack of this feature and I am sure that there are
people like me. At Stackoverflow and community forum there are posts
regarding it. At current situation we are reluctantly using as you proposed
but as I mentioned before it is usability it is really annoying.
By the way maybe it is right time to say, these validations are used in a
production system more than 150 million page view per month. Thanks experts
for your efforts for a better community.
On 4 January 2012 15:32, <beanvalidation-dev-request(a)lists.jboss.org> wrote:
> Hi,
> Let me try and summarize what you want to be sure we are on the same page:
>
> - you want sometimes to return one and only one failure per property
> - you want some constraints to be validated before others (to be the one
> displayed)
>
> Besides not empty which should be simply ignored by your unique email
> constraint, do you have other use cases? I would rather exclude null /
> empty from the list of use cases because it's a fairly pathological case
> and we plan on addressing that via a different mechanism (namely a way to
> mark a constraint validator as being called only on non null / non empty
> values).
>
> I've been trying to avoid numerical ordering (the fancy name is salience I
> believe) so far so I'd like to see concrete use cases that cannot be solved
> otherwise.
>
> Having a per property shortcut and a global shortcut would be a nice a
> easy feature to add. We left it out of 1.0 but it almost made it through.
>
> Likewise, we could fake salience by providing a special group
>
> ```
> package javax.validation.groups;
>
> @GroupSequence({Level1.class, Level2.class, Level3.class, Level4.class,
> Level5.class, Level6.class, Level7.class, Level8.class, Level9.class,
> Level10.class})
> interface Order {
> interface Level1 {}
> interface Level2 {}
> interface Level3 {}
> ...
> interface Level10 {}
> }
> ```
>
> Frankly I'd rather avoid it but that would work.
>
12 years, 11 months
Overriding constraints in inheritance hierarchies
by Gunnar Morling
Hi experts,
just recently there was a ticket created in the HV tracker [1] which
suggests to provide a way for "overriding" constraints within
inheritance hierarchies, i.e. the constraints defined on a property of
a parent bean are re-defined on the same property on an inherited bean
type (instead of being added up).
The approach suggested in the ticket doesn't work as described there,
as it isn't possible to define a generic array of constraint
annotations. Nevertheless it might be useful to have a means of
disabling the constraints from super types in special cases.
That said, I personally didn't have that requirement yet, but it makes
sense to me that someone might find this useful.
Any thoughts?
--Gunnar
[1] https://hibernate.onjira.com/browse/HV-548
12 years, 12 months