Hibernate.org Community Documentation

- Prev
- Next

## Chapter 10. Integrating with other frameworks

Hibernate Validator is intended to be used to implement multi-layered data validation, where constraints are expressed in a single place (the annotated domain model) and checked in various different layers of the application. For this reason there are multiple integration points with other technologies.

## 10.1. ORM integration

Hibernate Validator integrates with both Hibernate and all pure Java Persistence providers.

## Tip

When lazy loaded associations are supposed to be validated it is recommended to place the constraint on the getter of the association. Hibernate replaces lazy loaded associations with proxy instances which get initialized/loaded when requested via the getter. If, in such a case, the constraint is placed on field level the actual proxy instance is used which will lead to validation errors.

### 10.1.1. Database schema-level validation

Out of the box, Hibernate (as of version 3.5.x) will translate the constraints you have defined for your entities into mapping metadata. For example, if a property of your entity is annotated `@NotNull`, its columns will be declared as `not null` in the DDL schema generated by Hibernate.

If, for some reason, the feature needs to be disabled, set `hibernate.validator.apply_to_ddl` to `false`. See also Table 2.2, “Bean Validation constraints” and Table 2.3, “Custom constraints”.

You can also limit the DDL constraint generation to a subset of the defined constraints by setting the property org.hibernate.validator.group.ddl. The property specifies the comma-separated, fully specified class names of the groups a constraint has to be part of in order to be considered for DDL schema generation.

### 10.1.2. Hibernate event-based validation

Hibernate Validator has a built-in Hibernate event listener - `org.hibernate.cfg.beanvalidation.BeanValidationEventListener` - which is part of Hibernate Annotations (as of Hibernate 3.5.x). Whenever a `PreInsertEvent`, `PreUpdateEvent` or `PreDeleteEvent` occurs, the listener will verify all constraints of the entity instance and throw an exception if any constraint is violated. Per default objects will be checked before any inserts or updates are made by Hibernate. Pre deletion events will per default not trigger a validation. You can configure the groups to be validated per event type using the properties javax.persistence.validation.group.pre-persist, javax.persistence.validation.group.pre-update and javax.persistence.validation.group.pre-remove. The values of these properties are the comma-separated, fully specified class names of the groups to validate. Example 10.1, “Manual configuration of BeanValidationEvenListener” shows the default values for these properties. In this case they could also be omitted.

On constraint violation, the event will raise a runtime `ConstraintViolationException` which contains a set of `ConstraintViolation`s describing each failure.

If Hibernate Validator is present in the classpath, Hibernate Annotations (or Hibernate EntityManager) will use it transparently. To avoid validation even though Hibernate Validator is in the classpath set javax.persistence.validation.mode to `none`.

## Note

If the beans are not annotated with validation annotations, there is no runtime performance cost.

In case you need to manually set the event listeners for Hibernate Core, use the following configuration in `hibernate.cfg.xml`:

Example 10.1. Manual configuration of `BeanValidationEvenListener`

    <hibernate-configuration>

        <session-factory>

            ...

            <property name="javax.persistence.validation.group.pre-persist">

                javax.validation.groups.Default

            </property>

            <property name="javax.persistence.validation.group.pre-update">

                javax.validation.groups.Default

            </property>

            <property name="javax.persistence.validation.group.pre-remove"></property>

            ...

            <event type="pre-update">

                <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>

            </event>

            <event type="pre-insert">

                <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>

            </event>

            <event type="pre-delete">

                <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>

            </event>

        </session-factory>

    </hibernate-configuration>

### 10.1.3. JPA

If you are using JPA 2 and Hibernate Validator is in the classpath the JPA2 specification requires that Bean Validation gets enabled. The properties javax.persistence.validation.group.pre-persist, javax.persistence.validation.group.pre-update and javax.persistence.validation.group.pre-remove as described in Section 10.1.2, “Hibernate event-based validation” can in this case be configured in `persistence.xml`. `persistence.xml` also defines a node validation-mode which can be set to `AUTO`, `CALLBACK`, `NONE`. The default is `AUTO`.

In a JPA 1 you will have to create and register Hibernate Validator yourself. In case you are using Hibernate EntityManager you can add a customized version of the `BeanValidationEventListener` described in Section 10.1.2, “Hibernate event-based validation” to your project and register it manually.

## 10.2. JSF & Seam

When working with JSF2 or JBoss Seam™ and Hibernate Validator (Bean Validation) is present in the runtime environment, validation is triggered for every field in the application. Example 10.2, “Usage of Bean Validation within JSF2” shows an example of the f:validateBean tag in a JSF page. The validationGroups attribute is optional and can be used to specify a comma seperated list of validation groups. The default is `javax.validation.groups.Default`. For more information refer to the Seam documentation or the JSF 2 specification.

Example 10.2. Usage of Bean Validation within JSF2

    <h:form>

    <f:validateBean validationGroups="javax.validation.groups.Default">

        <h:inputText value=#{model.property} />

        <h:selectOneRadio value=#{model.radioProperty} > ... </h:selectOneRadio>

        <!-- other input components here -->

    </f:validateBean>

    </h:form>

## Tip

The integration between JSF 2 and Bean Validation is described in the "Bean Validation Integration" chapter of JSR-314. It is interesting to know that JSF 2 implements a custom `MessageInterpolator` to ensure ensure proper localization. To encourage the use of the Bean Validation message facility, JSF 2 will per default only display the generated Bean Validation message. This can, however, be configured via the application resource bundle by providing the following configuration (`{0}` is replaced with the Bean Validation message and `{1}` is replaced with the JSF component label):

    javax.faces.validator.BeanValidator.MESSAGE={1}: {0}

The default is:

    javax.faces.validator.BeanValidator.MESSAGE={0}

## 10.3. CDI

As of version 1.1, Bean Validation is integrated with CDI (Contexts and Dependency Injection for JavaTM EE).

This integration provides CDI managed beans for `Validator` and `ValidatorFactory` and enables dependency injection in constraint validators as well as custom message interpolators, traversable resolvers, constraint validator factories and parameter name providers.

Furthermore, parameter and return value constraints on the methods and constructors of CDI managed beans will automatically be validated upon invocation.

When your application runs on a Jave EE container, this integration is enabled by default. When working with CDI in a Servlet container or in a pure Java SE environment, you can use the CDI portable extension provided by Hibernate Validator. To do so, add the portable extension to your class path as described in Section 1.1.2, “CDI”.

### 10.3.1. Dependency injection

CDI's dependency injection mechanism makes it very easy to retrieve `ValidatorFactory` and `Validator` instances and use them in your managed beans. Just annotate instance fields of your bean with `@javax.inject.Inject` as shown in Example 10.3, “Retrieving validator factory and validator via @Inject”.

Example 10.3. Retrieving validator factory and validator via `@Inject`

    package org.hibernate.validator.referenceguide.chapter10.cdi.validator;

    @ApplicationScoped

    public class RentalStation {

        @Inject

        private ValidatorFactory validatorFactory;

        @Inject

        private Validator validator;

        //...

    }

The injected beans are the default validator factory and validator instances. In order to configure them - e.g. to use a custom message interpolator - you can use the Bean Validation XML descriptors as discussed in Chapter 7, Configuring via XML.

If you are working with several Bean Validation providers you can make sure that factory and validator from Hibernate Validator are injected by annotating the injection points with the `@HibernateValidator` qualifier which is demonstrated in Example 10.4, “Using the @HibernateValidator qualifier annotation”.

Example 10.4. Using the @HibernateValidator qualifier annotation

    package org.hibernate.validator.referenceguide.chapter10.cdi.validator.qualifier;

    @ApplicationScoped

    public class RentalStation {

        @Inject

        @HibernateValidator

        private ValidatorFactory validatorFactory;

        @Inject

        @HibernateValidator

        private Validator validator;

        //...

    }

## Tip

The fully-qualified name of the qualifier annotation is `org.hibernate.validator.cdi.HibernateValidator`. Be sure to not import `org.hibernate.validator.HibernateValidator` instead which is the `ValidationProvider` implementation used for selecting Hibernate Validator when working with the bootstrapping API (see Section 8.1, “Retrieving ValidatorFactory and Validator”).

Via `@Inject` you also can inject dependencies into constraint validators and other Bean Validation objects such as `MessageInterpolator` implementations etc.

Example 10.5, “Constraint validator with injected bean” demonstrates how an injected CDI bean is used in a `ConstraintValidator` implementation to determine whether the given constraint is valid or not. As the example shows, you also can work with the `@PostConstruct` and `@PreDestroy` callbacks to implement any required construction and destruction logic.

Example 10.5. Constraint validator with injected bean

    package org.hibernate.validator.referenceguide.chapter10.cdi.injection;

    public class ValidLicensePlateValidator

            implements ConstraintValidator<ValidLicensePlate, String> {

        @Inject

        private VehicleRegistry vehicleRegistry;

        @PostConstruct

        public void postConstruct() {

            //do initialization logic...

        }

        @PreDestroy

        public void preDestroy() {

            //do destruction logic...

        }

        @Override

        public void initialize(ValidLicensePlate constraintAnnotation) {

        }

        @Override

        public boolean isValid(String licensePlate, ConstraintValidatorContext constraintContext) {

            return vehicleRegistry.isValidLicensePlate( licensePlate );

        }

    }

### 10.3.2. Method validation

The method interception facilities of CDI allow for a very tight integration with Bean Validation's method validation functionality. Just put constraint annotations to the parameters and return values of the executables of your CDI beans and they will be validated automatically before (parameter constraints) and after (return value constraints) a method or constructor is invoked.

Note that no explicit interceptor binding is required, instead the required method validation interceptor will automatically be registered for all managed beans with constrained methods and constructors.

You can see an example in Example 10.6, “CDI managed beans with method-level constraints”.

Example 10.6. CDI managed beans with method-level constraints

    package org.hibernate.validator.referenceguide.chapter10.cdi.methodvalidation;

    @ApplicationScoped

    public class RentalStation {

        @Valid

        public RentalStation() {

            //...

        }

        @NotNull

        @Valid

        public Car rentCar(

                @NotNull Customer customer,

                @NotNull @Future Date startDate,

                @Min(1) int durationInDays) {

            //...

        }

        @NotNull

        List<Car> getAvailableCars() {

            //...

        }

    }

    package org.hibernate.validator.referenceguide.chapter10.cdi.methodvalidation;

    @RequestScoped

    public class RentCarRequest {

        @Inject

        private RentalStation rentalStation;

        public void rentCar(String customerId, Date startDate, int duration) {

            //causes ConstraintViolationException

            rentalStation.rentCar( null, null, -1 );

        }

    }

Here the `RentalStation` bean hosts several method constraints. When invoking one of the `RentalStation` methods from another bean such as `RentCarRequest`, the constraints of the invoked method are automatically validated. If any illegal parameter values are passed as in the example, a `ConstraintViolationException` will be thrown by the method interceptor, providing detailed information on the violated constraints. The same is the case if the method's return value violates any return value constraints.

Similarly, constructor constraints are validated automatically upon invocation. In the example the `RentalStation` object returned by the constructor will be validated since the constructor return value is marked with `@Valid`.

#### 10.3.2.1. Validated executable types

Bean Validation allows for a fine-grained control of the executable types which are automatically validated. By default, constraints on constructors and non-getter methods are validated. Therefore the `@NotNull` constraint on the method `RentalStation#getAvailableCars()` in Example 10.6, “CDI managed beans with method-level constraints” gets not validated when the method is invoked.

You have the following options to configure which types of executables are validated upon invocation:

- Configure the executable types globally via the XML descriptor `META-INF/validation.xml`; see Section 7.1, “Configuring the validator factory in validation.xml” for an example

- Use the `@ValidateOnExecution` annotation on the executable or type level

If several sources of configuration are specified for a given executable, `@ValidateOnExecution` on the executable level takes precedence over `@ValidateOnExecution` on the type level and `@ValidateOnExecution` generally takes precedence over the globally configured types in ``META-INF/validation.xml``.

Example 10.7, “Using @ValidateOnExecution” shows how to use the `@ValidateOnExecution` annotation:

Example 10.7. Using `@ValidateOnExecution`

    package org.hibernate.validator.referenceguide.chapter10.cdi.methodvalidation.configuration;

    @ApplicationScoped

    @ValidateOnExecution(type = ExecutableType.ALL)

    public class RentalStation {

        @Valid

        public RentalStation() {

            //...

        }

        @NotNull

        @Valid

        @ValidateOnExecution(type = ExecutableType.NONE)

        public Car rentCar(

                @NotNull Customer customer,

                @NotNull @Future Date startDate,

                @Min(1) int durationInDays) {

            //...

        }

        @NotNull

        public List<Car> getAvailableCars() {

            //...

        }

    }

Here the method `rentCar()` won't be validated upon invocation because it is annotated with `@ValidateOnExecution(type = ExecutableType.NONE)`. In contrast, the constructor and the method `getAvailableCars()` will be validated due to `@ValidateOnExecution(type = ExecutableType.ALL)` being given on the type level. `ExecutableType.ALL` is a more compact form for explicitly specifying all the types `CONSTRUCTORS`, `GETTER_METHODS` and `NON_GETTER_METHODS`.

## Tip

Executable validation can be turned off globally by specifying `<executable-validation enabled="false"/>` in `META-INF/validation.xml`. In this case, any `@ValidateOnExecution` annotations are ignored.

Note that when a method overrides or implements a super-type method the configuration will be taken from that overridden or implemented method (as given via `@ValidateOnExecution` on the method itself or on the super-type). This protects a client of the super-type method from an unexpected alteration of the configuration, e.g. disabling validation of an overridden executable in a sub-type.

In case a CDI managed bean overrides or implements a super-type method and this super-type method hosts any constraints, it can happen that the validation interceptor is not properly registered with the bean, resulting in the bean's methods not being validated upon invocation. In this case you can specify the executable type IMPLICIT on the sub-class as shown in Example 10.8, “Using ExecutableType.IMPLICIT”, which makes sure that all required metadata is discovered an the validation interceptor kicks in when the methods on `ExpressRentalStation` are invoked.

Example 10.8. Using `ExecutableType.IMPLICIT`

    package org.hibernate.validator.referenceguide.chapter10.cdi.methodvalidation.implicit;

    @ValidateOnExecution(type = ExecutableType.ALL)

    public interface RentalStation {

        @NotNull

        @Valid

        Car rentCar(

                @NotNull Customer customer,

                @NotNull @Future Date startDate,

                @Min(1) int durationInDays);

    }

    package org.hibernate.validator.referenceguide.chapter10.cdi.methodvalidation.implicit;

    @ApplicationScoped

    @ValidateOnExecution(type = ExecutableType.IMPLICIT)

    public class ExpressRentalStation implements RentalStation {

        @Override

        public Car rentCar(Customer customer, Date startDate, @Min(1) int durationInDays) {

            //...

        }

    }

## 10.4. Java EE

When your application runs on a Java EE application server such as WildFly, you also can obtain `Validator` and `ValidatorFactory` instances via `@Resource` injection in managed objects such as EJBs etc., as shown in Example 10.9, “Retrieving Validator and ValidatorFactory via @Resource injection”.

Example 10.9. Retrieving `Validator` and `ValidatorFactory` via `@Resource` injection

    package org.hibernate.validator.referenceguide.chapter10.javaee;

    @Stateless

    public class RentalStationBean {

        @Resource

        private ValidatorFactory validatorFactory;

        @Resource

        private Validator validator;

        //...

    }

Alternatively you can obtain a validator and a validator factory from JNDI under the names "java:comp/Validator" and "java:comp/ValidatorFactory", respectively.

Similar to CDI-based injection via `@Inject`, these objects represent default validator and validator factory and thus can be configured using the XML descriptor `META-INF/validation.xml` (see Chapter 7, Configuring via XML).

When your application is CDI-enabled, the injected objects are CDI-aware as well and e.g. support dependency injection in constraint validators.

Copyright © 2009 - 2013 Red Hat, Inc. & Gunnar Morling

- PrevChapter 9. Using constraint metadata
- Top of page
- Front page
- NextChapter 11. Hibernate Validator Specifics