[[validator-integration]] == 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. [[validator-checkconstraints-orm]] === ORM integration Hibernate Validator integrates with both Hibernate ORM 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 ORM 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. ==== [[validator-checkconstraints-db]] ==== Database schema-level validation Out of the box, Hibernate ORM 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 ORM. If, for some reason, the feature needs to be disabled, set `hibernate.validator.apply_to_ddl` to `false`. See also <> and <>. 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. [[validator-checkconstraints-orm-hibernateevent]] ==== Hibernate ORM event-based validation Hibernate Validator has a built-in Hibernate event listener - https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java[`org.hibernate.cfg.beanvalidation.BeanValidationEventListener`] - which is part of Hibernate ORM. 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 ORM. Pre deletion events will per default not trigger a validation. You can configure the groups to be validated per event type using the properties `jakarta.persistence.validation.group.pre-persist`, `jakarta.persistence.validation.group.pre-update` and `jakarta.persistence.validation.group.pre-remove`. The values of these properties are the comma-separated fully specified class names of the groups to validate. <> 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` instances describing each failure. If Hibernate Validator is present in the classpath, Hibernate ORM will use it transparently. To avoid validation even though Hibernate Validator is in the classpath, set `jakarta.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 ORM, use the following configuration in _hibernate.cfg.xml_: [[example-beanvalidationeventlistener-config]] .Manual configuration of `BeanValidationEvenListener` ==== [source, XML] ---- ... jakarta.validation.groups.Default jakarta.validation.groups.Default ... ---- ==== ==== Jakarta Persistence If you are using Jakarta Persistence {versionJakartaPersistence} and Hibernate Validator is in the classpath, the Jakarta Persistence {versionJakartaPersistence} specification requires that Jakarta Validation gets enabled. The properties `jakarta.persistence.validation.group.pre-persist`, `jakarta.persistence.validation.group.pre-update` and `jakarta.persistence.validation.group.pre-remove` as described in <> can in this case be configured in _persistence.xml_. _persistence.xml_ also defines a node validation-mode which can be set to `AUTO`, `CALLBACK` or `NONE`. The default is `AUTO`. [[section-presentation-layer]] === JSF & Seam When working with JSF2 or JBoss Seam and Hibernate Validator (Jakarta Validation) is present in the runtime environment, validation is triggered for every field in the application. <> 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 separated list of validation groups. The default is `jakarta.validation.groups.Default`. For more information refer to the Seam documentation or the JSF 2 specification. [[example-jsf2]] .Usage of Jakarta Validation within JSF2 ==== [source, XML] ---- ... ---- ==== [TIP] ==== The integration between JSF 2 and Jakarta Validation is described in the "Jakarta Validation Integration" chapter of http://jcp.org/en/jsr/detail?id=314[JSR-314]. It is interesting to know that JSF 2 implements a custom `MessageInterpolator` to ensure proper localization. To encourage the use of the Jakarta 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 Jakarta Validation message and `{1}` is replaced with the JSF component label): ---- jakarta.faces.validator.BeanValidator.MESSAGE={1}: {0} ---- The default is: ---- jakarta.faces.validator.BeanValidator.MESSAGE={0} ---- ==== [[section-integration-with-cdi]] === CDI As of version 1.1, Bean Validation (and therefore Jakarta Validation) is integrated with CDI (Contexts and Dependency Injection for Jakarta 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, parameter name providers, clock providers and value extractors. 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 Jakarta 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 <>. ==== 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 `@jakarta.inject.Inject` as shown in <>. [[example-dependency-injection]] .Retrieving validator factory and validator via `@Inject` ==== [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/cdi/validator/RentalStation.java[tags=include] ---- ==== 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 Jakarta Validation XML descriptors as discussed in <>. If you are working with several Jakarta 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-dependency-injection-using-hv]] .Using the `@HibernateValidator` qualifier annotation ==== [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/cdi/validator/qualifier/RentalStation.java[tags=include] ---- ==== [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 <>). ==== Via `@Inject` you also can inject dependencies into constraint validators and other Jakarta Validation objects such as `MessageInterpolator` implementations etc. <> 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-constraint-validator-injected-bean]] .Constraint validator with injected bean ==== [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/cdi/injection/ValidLicensePlateValidator.java[tags=include] ---- ==== ==== Method validation The method interception facilities of CDI allow for a very tight integration with Jakarta 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. [NOTE] ==== The interceptor `org.hibernate.validator.cdi.interceptor.spi.ValidationInterceptor` is registered by `org.hibernate.validator.cdi.ValidationExtension`. This happens implicitly within a Jakarta EE runtime environment or explicitly by adding the _hibernate-validator-cdi_ artifact - see <> ==== You can see an example in <>. [[example-cdi-method-validation]] .CDI managed beans with method-level constraints ==== [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/cdi/methodvalidation/RentalStation.java[tags=include] ---- [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/cdi/methodvalidation/RentCarRequest.java[tags=include] ---- ==== 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`. ===== Validated executable types Jakarta 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 <> does not get 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 <> 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__. <> shows how to use the `@ValidateOnExecution` annotation: [[example-using-validateonexecution]] .Using `@ValidateOnExecution` ==== [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/cdi/methodvalidation/configuration/RentalStation.java[tags=include] ---- ==== 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 `` in _META-INF/validation.xml_. In this case, all the `@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 <>, which makes sure that all required metadata is discovered and the validation interceptor kicks in when the methods on `ExpressRentalStation` are invoked. [[example-using-executabletype-implicit]] .Using `ExecutableType.IMPLICIT` ==== [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/cdi/methodvalidation/implicit/RentalStation.java[tags=include] ---- [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/cdi/methodvalidation/implicit/ExpressRentalStation.java[tags=include] ---- ==== === Jakarta EE When your application runs on a Jakarta EE application server such as http://wildfly.org/[WildFly], you also can obtain `Validator` and `ValidatorFactory` instances via `@Resource` injection in managed objects such as EJBs etc., as shown in <>. [[example-validator-resource-injection]] .Retrieving `Validator` and `ValidatorFactory` via `@Resource` injection ==== [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/javaee/RentalStationBean.java[tags=include] ---- ==== 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 <>). When your application is CDI-enabled, the injected objects are CDI-aware as well and e.g. support dependency injection in constraint validators. === JavaFX Hibernate Validator also provides support for the unwrapping of JavaFX properties. If JavaFX is present on the classpath, ``ValueExtractor``s for JavaFX properties are automatically registered. See <> for examples and further discussion. [[validator-osgi]] === OSGi Starting with Hibernate Validator 9.0, the Hibernate team no longer tests nor maintains the OSGi integration. For users who would want to experiment with Hibernate Validator in an OSGi environment, we will keep the existing manifest entries in place as they were.