Waqar Babar
Waqar Babar

Reputation: 129

Hibernate Validations ordering

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.

Upvotes: 2

Views: 1380

Answers (1)

hc_dev
hc_dev

Reputation: 9418

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.

Upvotes: 2

Related Questions