Hibernate.orgCommunity Documentation
In this chapter you will learn how to make use of several features provided by Hibernate Validator in addition to the functionality defined by the Bean Validation specification. This includes the fail fast mode, the API for programmatic constraint configuration and the boolean composition of constraints.
Using the features described in the following sections may result in application code which is not portable between Bean Validation providers.
Let's start, however, with a look at the public API of Hibernate Validator. Table 11.1, “Hibernate Validator public API” lists all packages belonging to this API and describes their purpose. Note that when a package is part of the public this is not necessarily true for its sub-packages.
Table 11.1. Hibernate Validator public API
| Packages | Description | 
|---|---|
| org.hibernate.validator | Classes used by the Bean Validation bootstrap mechanism (eg. validation provider, configuration class); For more details see Chapter 8, Bootstrapping. | 
| org.hibernate.validator.cfg, org.hibernate.validator.cfg.context, org.hibernate.validator.cfg.defs | Hibernate Validator's fluent API for constraint
            declaration; In org.hibernate.validator.cfg you
            will find the ConstraintMapping interface
            and in org.hibernate.validator.cfg.defs all
            constraint definitions. Refer to Section 11.3, “Programmatic constraint declaration” for the details. | 
| org.hibernate.validator.constraints, org.hibernate.validator.constraints.br | Some useful custom constraints provided by Hibernate Validator in addition to the built-in constraints defined by the Bean Validation specification; The constraints are described in detail in Section 2.3.2, “Additional constraints”. | 
| org.hibernate.validator.group, org.hibernate.validator.spi.group | The group sequence provider feature which allows you to define dynamic default group sequences in function of the validated object state; The specifics can be found in Section 5.3, “Redefining the default group sequence”. | 
| org.hibernate.validator.messageinterpolation, org.hibernate.validator.resourceloading, org.hibernate.validator.spi.resourceloading | Classes related to constraint message interpolation; The
            first package contains Hibernate Validator's default message
            interpolator,
            ResourceBundleMessageInterpolator. The
            latter two packages provide the
            ResourceBundleLocator SPI for the loading of resource
            bundles (see Section 4.2.1, “ResourceBundleLocator”)
            and its default implementation. | 
The public packages of Hibernate Validator fall into two
      categories: while the actual API parts are intended to be
      invoked or used by clients
      (e.g. the API for programmatic constraint declaration or the custom
      constraints), the SPI (service provider interface) packages contain
      interfaces which are intended to be implemented by
      clients (e.g. ResourceBundleLocator).
Any packages not listed in that table are internal packages of Hibernate Validator and are not intended to be accessed by clients. The contents of these internal packages can change from release to release without notice, thus possibly breaking any client code relying on it.
Using the fail fast mode, Hibernate Validator allows to return from the current validation as soon as the first constraint violation occurs. This can be useful for the validation of large object graphs where you are only interested in a quick check whether there is any constraint violation at all.
Example 11.1, “Using the fail fast validation mode” shows how to bootstrap and use a fail fast enabled validator.
Example 11.1. Using the fail fast validation mode
package org.hibernate.validator.referenceguide.chapter11.failfast;
public class Car {
@NotNull
private String manufacturer;
@AssertTrue
private boolean isRegistered;
public Car(String manufacturer, boolean isRegistered) {
this.manufacturer = manufacturer;
this.isRegistered = isRegistered;
}
//getters and setters...
}
Validator validator = Validation.byProvider( HibernateValidator.class )
.configure()
.failFast( true )
.buildValidatorFactory()
.getValidator();
Car car = new Car( null, false );
Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
assertEquals( 1, constraintViolations.size() );
Here the validated object actually fails to satisfy both the
    constraints declared on the Car class, yet the
    validation call yields only one ConstraintViolation
    since the fail fast mode is enabled.
There is no guarantee in which order the constraints are
      evaluated, i.e. it is not deterministic whether the returned violation
      originates from the @NotNull or the
      @AssertTrue constraint. If required, a
      deterministic evaluation order can be enforced using group sequences as
      described in Section 5.2, “Defining group sequences”.
Refer to Section 8.2.6, “Provider-specific settings” to learn about the different ways of enabling the fail fast mode when bootstrapping a validator.
As per the Bean Validation specification, you can declare constraints using Java annotations and XML based constraint mappings.
In addition, Hibernate Validator provides a fluent API which allows for the programmatic configuration of constraints. Use cases include the dynamic addition of constraints at runtime depending on some application state or tests where you need entities with different constraints in different scenarios but don't want to implement actual Java classes for each test case.
By default, constraints added via the fluent API are additive to constraints configured via the standard configuration capabilities. But it is also possible to ignore annotation and XML configured constraints where required.
The API is centered around the
    ConstraintMapping interface. You obtain a new
    mapping via
    HibernateValidatorConfiguration#createConstraintMapping()
    which you then can configure in a fluent manner as shown in Example 11.2, “Programmatic constraint declaration”.
Example 11.2. Programmatic constraint declaration
HibernateValidatorConfiguration configuration = Validation
.byProvider( HibernateValidator.class )
.configure();
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.type( Car.class )
.property( "manufacturer", FIELD )
.constraint( new NotNullDef() )
.property( "licensePlate", FIELD )
.ignoreAnnotations()
.constraint( new NotNullDef() )
.constraint( new SizeDef().min( 2 ).max( 14 ) )
.type( RentalCar.class )
.property( "rentalStation", METHOD )
.constraint( new NotNullDef() );
Validator validator = configuration.addMapping( constraintMapping )
.buildValidatorFactory()
.getValidator();
Constraints can be configured on multiple classes and properties
    using method chaining. The constraint definition classes
    NotNullDef and SizeDef are
    helper classes which allow to configure constraint parameters in a
    type-safe fashion. Definition classes exist for all built-in constraints
    in the org.hibernate.validator.cfg.defs package. By
    calling ignoreAnnotations() any constraints
    configured via annotations or XML are ignored for the given
    element.
Having configured the mapping, you must add it back to the configuration object from which you then can obtain a validator factory.
For custom constraints you can either create your own definition
    classes extending ConstraintDef or you can use
    GenericConstraintDef as seen in Example 11.3, “Programmatic declaration of a custom constraint”.
Example 11.3. Programmatic declaration of a custom constraint
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.type( Car.class )
.property( "licensePlate", FIELD )
.constraint( new GenericConstraintDef<CheckCase>( CheckCase.class )
.param( "value", CaseMode.UPPER )
);
By invoking valid() a member is marked for
    cascasded validation which is equivalent to annotating it with
    @Valid. An example can be seen in Example 11.4, “Marking a property for cascaded validation”.
Example 11.4. Marking a property for cascaded validation
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.type( Car.class )
.property( "driver", FIELD )
.constraint( new NotNullDef() )
.valid()
.type( Person.class )
.property( "name", FIELD )
.constraint( new NotNullDef() );
Not only bean constraints but also method constraints can be configured using the fluent API. As shown in Example 11.5, “Programmatic declaration of method constraints” methods are identified by their name and parameter types. Having selected a method, you can marke its parameters and/or return value for cascaded validation and add constraints.
Example 11.5. Programmatic declaration of method constraints
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.type( Car.class )
.method( "drive", int.class )
.parameter( 0 )
.constraint( new MaxDef().value ( 75 ) )
.method( "getDriver" )
.returnValue()
.constraint( new NotNullDef() )
.valid();
Last but not least you can configure the default group sequence or the default group sequence provider of a type as shown in the following example.
Example 11.6. Configuration of default group sequence and default group sequence provider
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.type( Car.class )
.defaultGroupSequence( Car.class, CarChecks.class )
.type( RentalCar.class )
.defaultGroupSequenceProviderClass( RentalCarGroupSequenceProvider.class );
Bean Validation specificies that the constraints of a composed
    constraint (see Section 6.4, “Constraint composition”) are all
    combined via a logical AND. This means all of the
    composing constraints need to return true in order
    for an overall successful validation.
Hibernate Validator offers an extension to this and allows you to
    compose constraints via a logical OR or
    NOT. To do so you have to use the
    ConstraintComposition annotation and the enum
    CompositionType with its values
    AND, OR and
    ALL_FALSE.
 Example 11.7, “OR composition of constraints” shows how
    to build a composed constraint @PatternOrSize where
    only one of the composing constraints needs to be valid in order to pass
    the validation. Either the validated string is all lower-cased or it is
    between two and three characters long.
Example 11.7. OR composition of constraints
package org.hibernate.validator.referenceguide.chapter11.booleancomposition;
@ConstraintComposition(OR)
@Pattern(regexp = "[a-z]")
@Size(min = 2, max = 3)
@ReportAsSingleViolation
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = { })
public @interface PatternOrSize {
String message() default "{org.hibernate.validator.referenceguide.chapter11." +
"booleancomposition.PatternOrSize.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
Using ALL_FALSE as composition type implicitly enforces that only a single violation will get reported in case validation of the constraint composition fails.
As described in Section 4.2, “Custom message interpolation”, Bean Validation allows to plug in custom message interpolator implementations.
With ResourceBundleLocator, Hibernate
    Validator provides an additional SPI which allows to retrieve error
    messages from other resource bundles than
    ValidationMessages while still using the actual
    interpolation algorithm as defined by the specification. Refer to Section 4.2.1, “ResourceBundleLocator” to learn how to make use of
    that SPI.
Copyright © 2009 - 2013 Red Hat, Inc. & Gunnar Morling