36

A field has two validation annotations

@NotEmpty
@Length(min=3,max=100)
String firstName;

Observation

If that field is left empty, then the resulting violations vary in order:

  • sometimes the @NotEmpty is violated first
  • other times the @Length is violated first

Questions

How does Hibernate specify the order in which validations (annotations) are processed? Can this validation order be customized?

Thanks in advance.

hc_dev
  • 8,389
  • 1
  • 26
  • 38
Mahmoud Saleh
  • 33,303
  • 119
  • 337
  • 498

2 Answers2

37

Use JSR-303 validation groups.

If no groups are specified a constraint is part of the Default Bean Validation group (see: javax.validation.groups.Default).

Create an interface to be your "Extended" (or whatever you want to call it) group:

public interface Extended{}

Now create an interface that will have the javax.validation.GroupSequence annotation.

@GroupSequence({Default.class, Extended.class})
public interface MySequence {}

Set the validation groups on your constraints

@NotEmpty // If no group is specified it is part of the default group
@Length(min=3,max=100, groups = Extended.class)
String firstName;

Pass MySequence to your validator call.

validator.validate(object, MySequence.class);

As specified by your @GroupSequence the default constraints will be validated first and if no contraint violations are encountered it will move on to the extended group.

Wilhelm Kleu
  • 10,821
  • 4
  • 36
  • 48
  • 4
    i am using @valid annotation, any other ideas ? – Mahmoud Saleh Apr 10 '11 at 15:59
  • 2
    I'm afraid I think you will have to wait for https://jira.springsource.org/browse/SPR-6373 to be resolved (or call the validator yourself). Have look at this article as well: http://digitaljoel.nerd-herders.com/2010/12/28/spring-mvc-and-jsr-303-validation-groups/ – Wilhelm Kleu Apr 11 '11 at 05:16
  • @MahmoudS You can setup a CDI decorator to handle this task, check this out: http://stackoverflow.com/questions/41325520/hibernate-error-with-custom-bean-validation – Marcos J.C Kichel Dec 26 '16 at 04:00
11

Just to add to the above answer, the group sequence could also be done at the Class level where validations have been defined. For example:

Provided we have two interfaces

public interface FirstOrder{}
public interface SecondOrder{}

We could define them as a group sequence as below

@GroupSequence({MyTestClass.class,FirstOrder.class,SecondOrder.class})
public class MyTestClass{

@NotBlank(groups = FirstOrder.class)    
@Length(min=3, max=100, groups = SecondOrder.class)
private String name; 

}

Advantage of doing the group sequence this way is -

You do not need an extra interface to define the group sequence and as a result you do not need to pass that to the validator for your unit/IT tests.

Radioactive
  • 611
  • 1
  • 11
  • 20