Hibernate Validator 4.1.0.Beta2 is out. A total of 29 issues got resolved since the last release and you can review then in the Jira changelog. Amongst others we added the @ScriptAssert constraints as promised in the previous release blog. Initially we wanted to release 4.1.0.CR directly, but we added a new programmatic constraint configuration API (HV-274) for which we want to first gather some feedback.

The new API is centered around ConstraintMapping which is the entry point to a fluent API allowing the configuration of constraints. The API is comparable to the one described in Emmanuel's blog Hibernate Search Programmatic Mapping API. But let's look at an example:

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 (we are also thinking about providing another annotation processor which at compile time could generate the required helper classes):

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.

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

Since the programmatic configuration is not part of the official Bean Validation specification you will have to get hold of HibernateValidatorConfiguration during the bootstrapping process in order to set your ConstraintMapping:

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

WDYT? Is this API useful? Easy to use? Anything we should consider/change?

If you want to play with this release, you can download it from the JBoss Maven repo or from SourceForge.


Back to top