Java Bean Validation 2.0 – Hibernate Validator Example

Bean validation in Java is supported via JSR-303 (Bean Validation 1.0), JSR-349 (Bean Validation 1.1) and JSR 380 (Bean Validation 2.0).

In this post, we will learn to use hibernate validator to validate the fields in Java bean. Bean validation API offers some very useful annotations that can be applied on a bean property for the purpose of maintaining data integrity.

1. Maven

Given below are the required hibernate validator maven dependencies.

Bean validation allows expressions inside the error messages. To parse these expressions, we must add a dependency on both the expression language API and an implementation of that API. I have added these using javax.el-api specification which is implemented in javax.el from Jboss.

<!-- Java bean validation API - Spec -->
<dependency>
	<groupId>javax.validation</groupId>
	<artifactId>validation-api</artifactId>
	<version>2.0.1.Final</version>
</dependency>

<!-- Hibernate validator - Bean validation API Implementation -->
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-validator</artifactId>
	<version>6.0.11.Final</version>
</dependency>

<!-- Verify validation annotations usage at compile time -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator-annotation-processor</artifactId>
  <version>6.0.11.Final</version>
</dependency>

<!-- Unified Expression Language - Spec -->
<dependency>
	<groupId>javax.el</groupId>
	<artifactId>javax.el-api</artifactId>
	<version>3.0.1-b06</version>
</dependency>

<!-- Unified Expression Language - Implementation -->
<dependency>
	<groupId>org.glassfish.web</groupId>
	<artifactId>javax.el</artifactId>
	<version>2.2.6</version>
</dependency>

2. Bean Validation Example

2.1. Model annotated with JSR-380 annotations

package com.howtodoinjava.example.model;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class User {

    @NotNull(message = "Please enter id")
    private Long id;

    @Size(max = 20, min = 3, message = "{user.name.invalid}")
    @NotEmpty(message = "Please enter name")
    private String name;

    @Email(message = "{user.email.invalid}")
    @NotEmpty(message = "Please enter email")
    private String email;

    public User(Long id, String name, String email) {
        super();
        this.id = id;
        this.name = name;
        this.email = email;
    }

    //Setters and Getters
}

2.2. Default Interpolation

By default, all messages are resolved from ValidationMessages.properties file in classpath. If file does not exist, the message resolution does not happen.

user.name.invalid=Invalid Username
user.email.invalid=Invalid Email

2.3. Executing Validation

Now let’s execute the bean validation on User instance.

package com.howtodoinjava.example;

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import com.howtodoinjava.example.model.User;

public class TestHibernateValidator 
{
    public static void main(String[] args) 
    {
        //Create ValidatorFactory which returns validator
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        
        //It validates bean instances
        Validator validator = factory.getValidator();

        User user = new User(null, "1", "abcgmail.com");

        //Validate bean
        Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);

        //Show errors
        if (constraintViolations.size() > 0) {
            for (ConstraintViolation<User> violation : constraintViolations) {
                System.out.println(violation.getMessage());
            }
        } else {
            System.out.println("Valid Object");
        }
    }
}

Program output:

Please enter id
Invalid Email
Invalid Username

3. Custom Resource Bundles

By default, framework picks up validation messages from ValidationMessages.properties file in classpath. We may configure the custom property files as below.

For example, put these two property files in classpath:

  • messages.properties
  • otherMessages.properties

Add both property files to ResourceBundleMessageInterpolator.

Validator validator = Validation.byDefaultProvider()
        .configure()
        .messageInterpolator(
                new ResourceBundleMessageInterpolator(
                        new AggregateResourceBundleLocator(
                                Arrays.asList(
                                        "messages",
                                        "otherMessages"
                                )
                        )
                )
        )
        .buildValidatorFactory()
        .getValidator();

4. Custom Message Interpolation

4.1. Parameters resolution in runtime

During message resolution, you can use runtime values to make validation messages more meaningful. This parameter value resolution in messages happen in two ways:

  1. To resolve values in annotation attributes, simply enclose the with curly braces. E.g. {min} or {max}.
  2. To resolve field’s runtime value, use placeholder ${validatedValue}.

4.2. Parameter value resolution example

  • Property file with message and parameters.
    user.name.invalid='${validatedValue}' is an invalid name. It must be minimum {min} chars and maximum {max} chars.
    
  • Bean field with validation annotation.
    @Size(max = 20, min = 3, message = "{user.name.invalid}")
    private String name;
    
  • Resolved message in program output.
    User user = new User(23l, "xy", "abc@gmail.com");
    Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
    

    Program Output.

    'xy' is an invalid name. It must be minimum 3 chars and maximum 20 chars.
    

5. Bean Validation Annotations List

Now when we know how to use hibernate validator in programmatic manner. Let’s go through all the annotations which you can use in bean classes.

5.1. Default Annotations

Annotation
Description
@Digits(integer=, fraction=)
Checks whether the annotated value is a number having up to integer digits and fraction fractional digits.
@Email
Checks whether the specified character sequence is a valid email address.
@Max(value=)
Checks whether the annotated value is less than or equal to the specified maximum.
@Min(value=)
Checks whether the annotated value is higher than or equal to the specified minimum
@NotBlank
Checks that the annotated character sequence is not null and the trimmed length is greater than 0.
@NotEmpty
Checks whether the annotated element is not null nor empty.
@Null
Checks that the annotated value is null
@NotNull
Checks that the annotated value is not null
@Pattern(regex=, flags=)
Checks if the annotated string matches the regular expression regex considering the given flag match
@Size(min=, max=)
Checks if the annotated element’s size is between min and max (inclusive)
@Negative
Checks if the element is strictly negative. Zero values are considered invalid.
@NegativeOrZero
Checks if the element is negative or zero.
@Future
Checks whether the annotated date is in the future.
@FutureOrPresent
Checks whether the annotated date is in the present or in the future.
@PastOrPresent
Checks whether the annotated date is in the past or in the present.

5.2. Hibernate validator specific annotations

In addition to the constraints defined by the Bean Validation API, Hibernate Validator provides several useful custom constraints which are listed below.

Annotation
Description
@CreditCardNumber( ignoreNonDigitCharacters=)
Checks that the annotated character sequence passes the Luhn checksum test. Note, this validation aims to check for user mistakes, not credit card validity!
@Currency(value=)
Checks that the currency unit of the annotated javax.money.MonetaryAmount is part of the specified currency units.
@EAN
Checks that the annotated character sequence is a valid EAN barcode. The default is EAN-13.
@ISBN
Checks that the annotated character sequence is a valid ISBN.
@Length(min=, max=)
Validates that the annotated character sequence is between min and max included.
@Range(min=, max=)
Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.
@UniqueElements
Checks that the annotated collection only contains unique elements.
@URL
Checks if the annotated character sequence is a valid URL according to RFC2396.

Drop me your questions in the comments section.

Happy Learning !!

References:

Bean Validation 2.0
Hibernate Validator Annotation Processor

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

1 thought on “Java Bean Validation 2.0 – Hibernate Validator Example”

  1. How to stop the next constraints checks for single field .
    for example there is bean User and has String userName;

    Certificate Number is mandatory

    here if first constraint fail means NotNull then i dont want check pattren check i have to stop here

    Certificate Number should not contain spaces
    .*[\S]+.*

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.