Hibernate.orgCommunity Documentation

Chapter 7. Programmatic constraint definition


Use of the features described in the following sections is not portable between Bean Validation providers/implementations.

Hibernate Validator allows to configure constraints not only via annotations and xml, but also via a programmatic API. This API can be used exclusively or in combination with annotations and xml. If used in combination programmatic constraints are additive to otherwise configured constraints.

The programmatic API is centered around the ConstraintMapping class which can be found together with its supporting classes in the org.hibernate.validator.cfg package. ConstraintMapping is the entry point to a fluent API allowing the definition of constraints. Example 7.1, “Programmatic constraint definition” shows how the API can be used.

Example 7.1. Programmatic constraint definition

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .property( "manufacturer", FIELD )
        .constraint( NotNullDef.class )
    .property( "licensePlate", FIELD )
        .constraint( NotNullDef.class )
        .constraint( SizeDef.class )
            .min( 2 )
            .max( 14 )
    .property( "seatCount", FIELD )
        .constraint( MinDef.class )
            .value ( 2 )
.type( RentalCar.class )
    .property( "rentalStation", METHOD)
        .constraint( NotNullDef.class );      

As you can see you can configure constraints on multiple classes and properties using method chaining. The constraint definition classes NotNullDef, SizeDef and MinDef are helper classes which allow to configure constraint parameters in a type-safe fashion. Definition classes exists for all built-in constraints in the org.hibernate.validator.cfg.defs package. For a custom constraint you can either create your own definition class extending ConstraintDef or you can use GenericConstraintDef as seen in Example 7.2, “Programmatic constraint definition using GenericConstraintDef”.

Example 7.2. Programmatic constraint definition using GenericConstraintDef

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .property( "licensePlate", FIELD )
        .constraint( GenericConstraintDef.class )
            .constraintType( CheckCase.class )
            .param( "value", CaseMode.UPPER );   

Last but not least, you can also define cascading constraints as well as the default group sequence of an entity.

Example 7.3. Cascading constraints and group redefinition

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .valid( "driver", FIELD )
.type( RentalCar.class)
    .defaultGroupSequence( RentalCar.class, CarChecks.class ); 

Once you have your ConstraintMapping you will have to pass it to the configuration. Since the programmatic configuration is not part of the official Bean Validation specification you will have to get hold of the Hibernate Validator specific configuration instance. See Example 7.4, “Creating a Hibernate Validator specific configuration”.

Example 7.4. Creating a Hibernate Validator specific configuration

ConstraintMapping mapping = new ConstraintMapping();
// configure mapping instance

HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();
config.addMapping( mapping );
ValidatorFactory factory = config.buildValidatorFactory();
Validator validator = factory.getValidator();