Hibernate.orgCommunity Documentation

Chapter 8. Bootstrapping

8.1. Retrieving ValidatorFactory and Validator
8.1.1. ValidationProviderResolver
8.2. Configuring a ValidatorFactory
8.2.1. MessageInterpolator
8.2.2. TraversableResolver
8.2.3. ConstraintValidatorFactory
8.2.4. ParameterNameProvider
8.2.5. Adding mapping streams
8.2.6. Provider-specific settings
8.3. Configuring a Validator

In Section 2.2.1, “Obtaining a Validator instance” you already saw one way for creating a Validator instance - via Validation#buildDefaultValidatorFactory(). In this chapter you will learn how to use the other methods in javax.validation.Validation in order to bootstrap specifically configured validators.

You obtain a Validator by retrieving a ValidatorFactory via one of the static methods on javax.validation.Validation and calling getValidator() on the factory instance.

Example 8.1, “Bootstrapping default ValidatorFactory and Validator shows how to obtain a validator from the default validator factory:


Tip

The generated ValidatorFactory and Validator instances are thread-safe and can be cached. As Hibernate Validator uses the factory as context for caching constraint metadata it is recommended to work with one factory instance within an application.

Bean Validation supports working with several providers such as Hibernate Validator within one application. If more than one provider is present on the classpath, it is not guaranteed which one is chosen when creating a factory via buildDefaultValidatorFactory().

In this case you can explicitly specify the provider to use via Validation#byProvider(), passing the provider’s ValidationProvider class as shown in Example 8.2, “Bootstrapping ValidatorFactory and Validator using a specific provider”.


Note that the configuration object returned by configure() allows to specifically customize the factory before calling buildValidatorFactory(). The available options are discussed later in this chapter.

Similarly you can retrieve the default validator factory for configuration which is demonstrated in Example 8.3, “Retrieving the default ValidatorFactory for configuration”.


Note

If a ValidatorFactory instance is no longer in use, it should be disposed by calling ValidatorFactory#close(). This will free any resources possibly allocated by the factory.

By default, available Bean Validation providers are discovered using the Java Service Provider mechanism.

For that purpose, each provider includes the file META- INF/services/javax.validation.spi.ValidationProvider, containing the fully qualified classname of its ValidationProvider implementation. In the case of Hibernate Validator this is org.hibernate.validator.HibernateValidator.

Depending on your environment and its classloading specifics, provider discovery via the Java’s service loader mechanism might not work. In this case you can plug in a custom ValidationProviderResolver implementation which performs the provider retrieval. An example is OSGi, where you could implement a provider resolver which uses OSGi services for provider discovery.

To use a custom provider resolver pass it via providerResolver() as shown shown in Example 8.4, “Using a custom ValidationProviderResolver.


By default validator factories retrieved from Validation and any validators they create are configured as per the XML descriptor META-INF/validation.xml (see Chapter 7, Configuring via XML), if present.

If you want to disable the XML based configuration, you can do so by invoking Configuration#ignoreXmlConfiguration().

The different values of the XML configuration can be accessed via Configuration#getBootstrapConfiguration(). This can for instance be helpful if you want to integrate Bean Validation into a managed environment and want to create managed instances of the objects configured via XML.

Using the fluent configuration API, you can override one or more of the settings when bootstrapping the factory. The following sections show how to make use of the different options. Note that the Configuration class exposes the default implementations of the different extension points which can be useful if you want to use these as delegates for your custom implementations.

In some cases the validation engine should not access the state of a bean property. The most obvious example for that is a lazily loaded property or association of a JPA entity. Validating this lazy property or association would mean that its state would have to be accessed, triggering a load from the database.

Which properties can be accessed and which ones not is controlled by querying the TraversableResolver interface. Example 8.6, “Using a custom TraversableResolver shows how to use a custom traversable resolver implementation.


If no specific traversable resolver has been configured, the default behavior is to consider all properties as reachable and cascadable. When using Hibernate Validator together with a JPA 2 provider such as Hibernate ORM, only those properties will be considered reachable which already have been loaded by the persistence provider and all properties will be considered cascadable.

ConstraintValidatorFactory is the extension point for customizing how constraint validators are instantiated and released.

The default ConstraintValidatorFactory provided by Hibernate Validator requires a public no-arg constructor to instantiate ConstraintValidator instances (see Section 6.1.2, “The constraint validator”). Using a custom ConstraintValidatorFactory offers for example the possibility to use dependency injection in constraint validator implementations.

To configure a custom constraint validator factory call Configuration#constraintValidatorFactory() (see Example 8.7, “Using a custom ConstraintValidatorFactory.


Warning

Any constraint implementations relying on ConstraintValidatorFactory behaviors specific to an implementation (dependency injection, no no-arg constructor and so on) are not considered portable.

Note

ConstraintValidatorFactory implementations should not cache validator instances as the state of each instance can be altered in the initialize() method.

In case a method or constructor parameter constraint is violated, the ParameterNameProvider interface is used to retrieve the parameter name and make it available to the user via the property path of the constraint violation.

The default implementation returns parameter names in the form of arg0, arg1 etc, while custom implementations can retrieve the parameter names using methods such as parameter annotations, debug symbols, or Java 8 reflection.

An implementation for retrieving the parameter names using reflection in Java 8 is provided with ReflectionParameterNameProvider. For this parameter name provider to work, the source must be compiled using the –parameters compiler argument. Otherwise, the provider will return synthetic names in the form of arg0, arg1, etc.

To use ReflectionParameterNameProvider or another custom provider either pass an instance of the provider during bootstrapping as shown in Example 8.8, “Using a custom ParameterNameProvider, or specify the fully qualified class name of the provider as value for the <parameter-name-provider> element in the META-INF/validation.xml file (see Section 7.1, “Configuring the validator factory in validation.xml). This is demonstrated in Example 8.8, “Using a custom ParameterNameProvider.


Tip

Hibernate Validator comes with a custom ParameterNameProvider implementation based on the ParaNamer library which provides several ways for obtaining parameter names at runtime. Refer to Section 11.10, “ParaNamer based ParameterNameProvider to learn more about this specific implementation.

When working with a configured validator factory it can occasionally be required to apply a different configuration to a single Validator instance. Example 8.12, “Configuring a Validator instance via usingContext() shows how this can be achieved by calling ValidatorFactory#usingContext().