1

I am using Hibernate Validations. If we pass several groups to validate() the order of the validation message is random. If two validations are applied to one field and both fail and those two validations belong to two different groups. is there any way to keep the order of the validations?

// Bean
public class Register {

    @Size(min = 8, max = 50, message = "Minimum should be 5 and maximum should be 10", groups=Second.class)
    public String username;

    @Size(min = 8, max = 50, message = "Minimum should be 5 and maximum should be 10", groups=Second.class)
    @Pattern(regexp = "(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]*", message = "incorrect format", groups=First.class)
    public String password;
}


// Validate call
Set<ConstraintViolation<T>> constraintViolations = validator.validate(o, First.class, Second.class);

the input is

username "test", password "test"

then all validation fails which is desired but for the password the order of the validation messages are random. I want the validation message of the First group should always appear first.

Waqar Babar
  • 109
  • 1
  • 7
  • Does this answer your question? [Control validation annotations order?](https://stackoverflow.com/questions/5571231/control-validation-annotations-order) – Vikas Jul 07 '20 at 11:36
  • @Code_Mode Nope, If I will use the GroupSequence then the validation will work in step by step. Like first it will check only for the first group if nothing fails then checks for the second group which is the wizard approach. I want to validate everything at once. – Waqar Babar Jul 07 '20 at 11:48
  • 1
    Sounds like you want to use validation groups to control the _display order_ of messages for a given field (e.g. for your password field, the pattern message is always listed first, before the size message). That is not what validation groups are designed to do - and you have probably already seen that the `groups` values are not available in each `ConstraintViolation` object. I think your best option is a poor one: Run `validator.validate()` twice. Once for `First.class`, and again for `Second.class`. Now you have the info you need to control the display order. – andrewJames Jul 07 '20 at 13:37

1 Answers1

2

Default: No particular validation order

The hibernate-validator docs state in 5.3. Defining group sequences:

By default, constraints are evaluated in no particular order, regardless of which groups they belong to. In some situations, however, it is useful to control the order in which constraints are evaluated.

and further:

In order to implement such a validation order you just need to define an interface and annotate it with @GroupSequence, defining the order in which the groups have to be validated (see Example 5.7, “Defining a group sequence”).

Defining a group sequence

Following given Example 5.7, “Defining a group sequence” you would reach desired order by defining an extra interface:

import jakarta.validation.GroupSequence;
import jakarta.validation.groups.Default;
// assume these validation-groups imported from your namespace
import your.validation.groups.First;
import your.validation.groups.Second;

@GroupSequence({ Default.class, First.class, Second.class })
public interface OrderedChecks {
}

Using the group sequence

Docs show how to use the new sequence in Example 5.8, “Using a group sequence”, adapted to your case.

// pass your Registration object along with the sequence class
validator.validate( registration, OrderedChecks.class );

⚠️ This solution is just theoretical and untested.

hc_dev
  • 8,389
  • 1
  • 26
  • 38