[[validator-specifics]]
== Hibernate Validator Specifics

In this chapter you will learn how to make use of several features provided by Hibernate Validator
in addition to the functionality defined by the Bean Validation specification. This includes the
fail fast mode, the API for programmatic constraint configuration and the boolean composition of
constraints.

New APIs or SPIs are tagged with the `org.hibernate.validator.Incubating` annotation as long as they
are under development. This means that such elements (e.g. packages, types, methods, constants etc.)
may be incompatibly altered - or removed - in subsequent releases. Usage of incubating API/SPI members
is encouraged (so the development team can get feedback on these new features) but you should be
prepared for updating code which is using them as needed when upgrading to a new version of Hibernate
Validator.

[NOTE]
====
Using the features described in the following sections may result in application code which is not
portable between Bean Validation providers.
====

=== Public API

Let's start, however, with a look at the public API of Hibernate Validator. Below you can find a list of all packages belonging to this API and their purpose.
Note that when a package is part of the public API this is not necessarily true for its sub-packages.

`org.hibernate.validator`::
			Classes used by the Bean Validation bootstrap mechanism (eg. validation provider, configuration class); for more details see <<chapter-bootstrapping>>.

`org.hibernate.validator.cfg`, `org.hibernate.validator.cfg.context`, `org.hibernate.validator.cfg.defs`, `org.hibernate.validator.spi.cfg`::
			Hibernate Validator's fluent API for constraint declaration; in `org.hibernate.validator.cfg` you will find the `ConstraintMapping` interface, in `org.hibernate.validator.cfg.defs` all constraint definitions and in `org.hibernate.validator.spi.cfg` a callback for using the API for configuring the default validator factory. Refer to <<section-programmatic-api>> for the details.

`org.hibernate.validator.constraints`, `org.hibernate.validator.constraints.br`, `org.hibernate.validator.constraints.pl`::
			Some useful custom constraints provided by Hibernate Validator in addition to the built-in constraints defined by the Bean Validation specification; the constraints are described in detail in <<validator-defineconstraints-hv-constraints>>.

`org.hibernate.validator.constraintvalidation`::
			Extended constraint validator context which allows to set custom attributes for message interpolation. <<section-hibernateconstraintvalidatorcontext>> describes how to make use of that feature.

`org.hibernate.validator.group`, `org.hibernate.validator.spi.group`::
			The group sequence provider feature which allows you to define dynamic default group sequences in function of the validated object state; the specifics can be found in <<section-default-group-class>>.

`org.hibernate.validator.messageinterpolation`, `org.hibernate.validator.resourceloading`, `org.hibernate.validator.spi.resourceloading`::
			Classes related to constraint message interpolation; the first package contains Hibernate Validator's default message interpolator, `ResourceBundleMessageInterpolator`. The latter two packages provide the `ResourceBundleLocator` SPI for the loading of resource bundles (see <<section-resource-bundle-locator>>) and its default implementation.

`org.hibernate.validator.parameternameprovider`::
			A `ParameterNameProvider` based on the Paranamer library, see <<section-paranamer-parameternameprovider>>.

`org.hibernate.validator.propertypath`::
			Extensions to the `javax.validation.Path` API, see <<section-extensions-path-api>>.

`org.hibernate.validator.spi.constraintdefinition`::
			An SPI for registering additional constraint validators programmatically, see <<section-constraint-definition-contribution>>.

[NOTE]
====
The public packages of Hibernate Validator fall into two categories: while the actual API parts are
intended to be _invoked_ or _used_ by clients (e.g. the API for programmatic constraint declaration
or the custom constraints), the SPI (service provider interface) packages contain interfaces which
are intended to be _implemented_ by clients (e.g. `ResourceBundleLocator`).
====

Any packages not listed in that table are internal packages of Hibernate Validator and are not
intended to be accessed by clients. The contents of these internal packages can change from release
to release without notice, thus possibly breaking any client code relying on it.

[[section-fail-fast]]
=== Fail fast mode

Using the fail fast mode, Hibernate Validator allows to return from the current validation as soon
as the first constraint violation occurs. This can be useful for the validation of large object
graphs where you are only interested in a quick check whether there is any constraint violation at
all.

<<example-using-fail-fast>> shows how to bootstrap and use a fail fast enabled validator.

[[example-using-fail-fast]]
.Using the fail fast validation mode
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/failfast/Car.java[tags=include]
----

[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/failfast/FailFastTest.java[tags=include]
----
====

Here the validated object actually fails to satisfy both the constraints declared on the `Car` class,
yet the validation call yields only one `ConstraintViolation` since the fail fast mode is enabled.

[NOTE]
====
There is no guarantee in which order the constraints are evaluated, i.e. it is not deterministic
whether the returned violation originates from the `@NotNull` or the `@AssertTrue` constraint. If
required, a deterministic evaluation order can be enforced using group sequences as described in
<<section-defining-group-sequences>>.
====

Refer to <<section-provider-specific-settings>> to learn about the different ways of enabling the
fail fast mode when bootstrapping a validator.

[[section-method-validation-prerequisite-relaxation]]
=== Relaxation of requirements for method validation in class hierarchies

The Bean Validation specification defines a set of preconditions which apply when defining
constraints on methods within class hierarchies. These preconditions are defined in
{bvSpecUrl}#constraintdeclarationvalidationprocess-methodlevelconstraints-inheritance[section 5.6.5]
of the Bean Validation 2.0 specification. See also <<section-method-constraints-inheritance-hierarchies>>
in this guide.

As per specification, a Bean Validation provider is allowed to relax these preconditions.
With Hibernate Validator you can do this in one of two ways.

First you can use the configuration properties _hibernate.validator.allow_parameter_constraint_override_,
_hibernate.validator.allow_multiple_cascaded_validation_on_result_ and
_hibernate.validator.allow_parallel_method_parameter_constraint_ in _validation.xml_. See example
<<example-relaxing-method-validation-xml>>.


[[example-relaxing-method-validation-xml]]
.Configuring method validation behaviour in class hierarchies via properties
====
[source, XML]
----
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
        xmlns="http://xmlns.jcp.org/xml/ns/validation/configuration"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/configuration validation-configuration-2.0.xsd"
        version="2.0">
    <default-provider>org.hibernate.validator.HibernateValidator</default-provider>

    <property name="hibernate.validator.allow_parameter_constraint_override">true</property>
    <property name="hibernate.validator.allow_multiple_cascaded_validation_on_result">true</property>
    <property name="hibernate.validator.allow_parallel_method_parameter_constraint">true</property>
</validation-config>
----
====

Alternatively these settings can be applied during programmatic bootstrapping.

[[example-relaxing-method-validation]]
.Configuring method validation behaviour in class hierarchies
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/relaxation/RelaxationTest.java[tags=testRelaxation]
----
====

By default, all of these properties are false, implementing the default behavior as defined in the
Bean Validation specification.

[WARNING]
====
Changing the default behaviour for method validation will result in non specification-conforming and non
portable application. Make sure to understand what you are doing and that your use case really
requires changes to the default behaviour.
====

[[section-programmatic-api]]
=== Programmatic constraint definition and declaration

As per the Bean Validation specification, you can define and declare constraints using Java annotations and XML
based constraint mappings.

In addition, Hibernate Validator provides a fluent API which allows for the programmatic
configuration of constraints. Use cases include the dynamic addition of constraints at runtime
depending on some application state or tests where you need entities with different constraints in
different scenarios but don't want to implement actual Java classes for each test case.

By default, constraints added via the fluent API are additive to constraints configured via the
standard configuration capabilities. But it is also possible to ignore annotation and XML configured
constraints where required.

The API is centered around the `ConstraintMapping` interface. You obtain a new mapping via
`HibernateValidatorConfiguration#createConstraintMapping()` which you then can configure in a fluent
manner as shown in <<example-constraint-mapping>>.

[[example-constraint-mapping]]
.Programmatic constraint declaration
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=constraintMapping]
----
====

Constraints can be configured on multiple classes and properties using method chaining. The
constraint definition classes `NotNullDef` and SizeDef are helper classes which allow to configure
constraint parameters in a type-safe fashion. Definition classes exist for all built-in constraints
in the `org.hibernate.validator.cfg.defs` package. By calling `ignoreAnnotations()` any constraints
configured via annotations or XML are ignored for the given element.

[NOTE]
====
Each element (type, property, method etc.) may only be configured once within all the constraint
mappings used to set up one validator factory. Otherwise a `ValidationException` is raised.
====

[NOTE]
====
It is not supported to add constraints to non-overridden supertype properties and methods by
configuring a subtype. Instead you need to configure the supertype in this case.
====

Having configured the mapping, you must add it back to the configuration object from which you then
can obtain a validator factory.

For custom constraints, you can either create your own definition classes extending `ConstraintDef` or
you can use `GenericConstraintDef` as seen in <<example-generic-constraint-mapping>>.

[[example-generic-constraint-mapping]]
.Programmatic declaration of a custom constraint
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=genericConstraintDef]
----
====

Container element constraints are supported by the programmatic API, using `containerElementType()`.

<<example-nested-container-element-constraints>> show an example where constraints are declared on
nested container elements.

[[example-nested-container-element-constraints]]
.Programmatic declaration of a nested container element constraint
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=nestedContainerElementConstraint]
----
====

As demonstrated, the parameters passed to `containerElementType()` are the path of type argument
indexes used to obtain the desired nested container element type.

By invoking `valid()` you can mark a member for cascaded validation which is equivalent to annotating
it with `@Valid`. Configure any group conversions to be applied during cascaded validation using the
`convertGroup()` method (equivalent to `@ConvertGroup`). An example can be seen in
<<example-cascading-constraints>>.

[[example-cascading-constraints]]
.Marking a property for cascaded validation
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=cascaded]
----
====

You can not only configure bean constraints using the fluent API but also method and constructor
constraints. As shown in <<example-method-constraint-mapping>> constructors are identified by their
parameter types and methods by their name and parameter types. Having selected a method or
constructor, you can mark its parameters and/or return value for cascaded validation and add
constraints as well as cross-parameter constraints.

As shown in the example, `valid()` can be also invoked on a container element type.

[[example-method-constraint-mapping]]
.Programmatic declaration of method and constructor constraints
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=executableConfiguration]
----
====

Last but not least you can configure the default group sequence or the default group sequence
provider of a type as shown in the following example.

[[example-sequences]]
.Configuration of default group sequence and default group sequence provider
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=defaultGroupSequence]
----
====

[[section-programmatic-api-contributor]]
=== Applying programmatic constraint declarations to the default validator factory

If you are not bootstrapping a validator factory manually
but work with the default factory as configured via _META-INF/validation.xml_
(see <<chapter-xml-configuration>>),
you can add one or more constraint mappings by creating one or several constraint mapping contributors.
To do so, implement the `ConstraintMappingContributor` contract:

[[example-constraint-mapping-contributor]]
.Custom `ConstraintMappingContributor` implementation
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/MyConstraintMappingContributor.java[tags=include]
----
====

You then need to specify the fully-qualified class name of the contributor implementation in _META-INF/validation.xml_,
using the property key `hibernate.validator.constraint_mapping_contributors`. You can specify several
contributors by separating them with a comma.

[[section-advanced-constraint-composition]]
=== Advanced constraint composition features

==== Validation target specification for purely composed constraints

In case you specify a purely composed constraint - i.e. a constraint which has no validator itself but is solely made
up from other, composing constraints - on a method declaration, the validation engine cannot determine whether that
constraint is to be applied as a return value constraint or as a cross-parameter constraint.

Hibernate Validator allows to resolve such ambiguities by specifying the `@SupportedValidationTarget` annotation on the
declaration of the composed constraint type as shown in <<example-purely-composed-constraint-validation-target>>.
The `@ValidInvoiceAmount` does not declare any validator, but it is solely composed by the `@Min` and `@NotNull`
constraints. The `@SupportedValidationTarget` ensures that the constraint is applied to the method return value when
given on a method declaration.

[[example-purely-composed-constraint-validation-target]]
.Specifying the validation target of a purely composed constraint
====
[source, JAVA]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/purelycomposed/ValidInvoiceAmount.java[tags=include]
----
====

[[section-boolean-constraint-composition]]
==== Boolean composition of constraints

Bean Validation specifies that the constraints of a composed constraint (see
<<section-constraint-composition>>) are all combined via a logical _AND_. This means all of the
composing constraints need to return true to obtain an overall successful validation.

Hibernate Validator offers an extension to this and allows you to compose constraints via a logical
_OR_ or _NOT_. To do so, you have to use the ConstraintComposition annotation and the enum
CompositionType with its values _AND_, _OR_ and _$$ALL_FALSE$$_.

<<example-boolean-constraint-composition>> shows how to build a composed constraint `@PatternOrSize`
where only one of the composing constraints needs to be valid in order to pass the validation.
Either the validated string is all lower-cased or it is between two and three characters long.

[[example-boolean-constraint-composition]]
.OR composition of constraints
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/booleancomposition/PatternOrSize.java[tags=include]
----
====

[TIP]
====
Using _$$ALL_FALSE$$_ as composition type implicitly enforces that only a single violation will get
reported in case validation of the constraint composition fails.
====

[[section-extensions-path-api]]
=== Extensions of the Path API

Hibernate Validator provides an extension to the `javax.validation.Path` API.
For nodes of `ElementKind.PROPERTY` and `ElementKind.CONTAINER_ELEMENT` it allows to obtain the value of the
represented property.
To do so, narrow down a given node to the type `org.hibernate.validator.path.PropertyNode` or
`org.hibernate.validator.path.ContainerElementNode` respectively using `Node#as()`, as
shown in the following example:

[[example-property-node-get-value]]
.Getting the value from property nodes
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/propertypath/PropertyPathTest.java[tags=include]
----
====

This is also very useful to obtain the element of `Set` properties on the property path (e.g. `apartments`
in the example) which otherwise could not be identified (unlike for `Map` and `List`, there is no key nor index
in this case).

[[section-dynamic-payload]]
=== Dynamic payload as part of `ConstraintViolation`

In some cases automatic processing of violations can be aided, if the constraint violation provides additional
data - a so called dynamic payload. This dynamic payload could for example contain hints to the user on how to
resolve the violation.

Dynamic payloads can be set in <<validator-customconstraints,custom constraints>> using `HibernateConstraintValidatorContext`.
This is shown in example <<example-constraint-validator-setting-dynamic-payload>> where the
`javax.validation.ConstraintValidatorContext` is unwrapped to `HibernateConstraintValidatorContext` in order to call
`withDynamicPayload`.

[[example-constraint-validator-setting-dynamic-payload]]
.`ConstraintValidator` implementation setting a dynamic payload
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/dynamicpayload/ValidPassengerCountValidator.java[tags=include]
----
====

On the constraint violation processing side, a `javax.validation.ConstraintViolation` can then in turn be
unwrapped to `HibernateConstraintViolation` in order to retrieve the dynamic payload for further processing.

[[example-retrieving-dynamic-payload]]
.Retrieval of a ``ConstraintViolation``'s dynamic payload
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/dynamicpayload/DynamicPayLoadTest.java[tags=include]
----
====

[[non-el-message-interpolator]]
=== `ParameterMessageInterpolator`

Hibernate Validator requires per default an implementation of the Unified EL (see
<<validator-gettingstarted-uel>>) to be available. This is needed to allow the interpolation
of constraint error messages using EL expressions as defined by the Bean Validation specification.

For environments where you cannot or do not want to provide an EL implementation, Hibernate Validator
offers a non EL based message interpolator - `org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator`.

Refer to <<section-custom-message-interpolation>> to see how to plug in custom message interpolator
implementations.

[WARNING]
====
Constraint messages containing EL expressions will be returned un-interpolated by
`org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator`. This also affects
built-in default constraint messages which use EL expressions. At the moment, `DecimalMin` and `DecimalMax` are affected.
====

=== `ResourceBundleLocator`

With `ResourceBundleLocator`, Hibernate Validator provides an additional SPI which allows to retrieve
error messages from other resource bundles than _ValidationMessages_ while still using the actual
interpolation algorithm as defined by the specification. Refer to
<<section-resource-bundle-locator>> to learn how to make use of that SPI.

=== Custom contexts

The Bean Validation specification offers at several points in its API the possibility to unwrap a
given interface to an implementor specific subtype. In the case of constraint violation creation in
`ConstraintValidator` implementations as well as message interpolation in `MessageInterpolator`
instances, there exist `unwrap()` methods for the provided context instances -
`ConstraintValidatorContext` respectively `MessageInterpolatorContext`. Hibernate Validator provides
custom extensions for both of these interfaces.

[[section-hibernateconstraintvalidatorcontext]]
==== `HibernateConstraintValidatorContext`

[[section-custom-constraint-validator-context]]
`HibernateConstraintValidatorContext` is a subtype of `ConstraintValidatorContext` which allows you to:

* set arbitrary parameters for interpolation via the Expression Language message interpolation
facility using `HibernateConstraintValidatorContext#addExpressionVariable(String, Object)`
or `HibernateConstraintValidatorContext#addMessageParameter(String, Object)`.
+
[[example-custom-expression-variable]]
.Custom `@Future` validator injecting an expression variable
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/context/MyFutureValidator.java[tags=include]
----
====
+
[[example-custom-message-parameter]]
.Custom `@Future` validator injecting a message parameter
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/context/MyFutureValidatorMessageParameter.java[tags=include]
----
====
+
[NOTE]
====
Apart from the syntax, the main difference between message parameters and expression variables is that message parameters
are simply interpolated whereas expression variables are interpreted using the expression language engine.
In practice, it should not change anything.
====
+
[NOTE]
====
Note that the parameters specified via `addExpressionVariable(String, Object)` and
`addMessageParameter(String, Object)` are global and apply to all constraint violations created by
this `isValid()` invocation.
This includes the default constraint violation, but also all violations created by the `ConstraintViolationBuilder`.
You can, however, update the parameters between invocations of
`ConstraintViolationBuilder#addConstraintViolation()`.
====
* set an arbitrary dynamic payload - see <<section-dynamic-payload>>

==== `HibernateMessageInterpolatorContext`

Hibernate Validator also offers a custom extension of `MessageInterpolatorContext`, namely
`HibernateMessageInterpolatorContext` (see <<example-custom-message-interpolator-context>>). This
subtype was introduced to allow a better integration of Hibernate Validator into Glassfish. The
root bean type was in this case needed to determine the right class loader for the message resource
bundle. If you have any other use cases, let us know.

[[example-custom-message-interpolator-context]]
.`HibernateMessageInterpolatorContext`
====
[source, JAVA, indent=0]
----
include::{engine-sourcedir}/org/hibernate/validator/messageinterpolation/HibernateMessageInterpolatorContext.java[lines=18..26]
----
====

[[section-paranamer-parameternameprovider]]
=== Paranamer based `ParameterNameProvider`

Hibernate Validator comes with a `ParameterNameProvider` implementation which leverages the
http://paranamer.codehaus.org/[Paranamer] library.

This library provides several ways for obtaining parameter names at runtime, e.g. based on debug
symbols created by the Java compiler, constants with the parameter names woven into the bytecode in
a post-compile step or annotations such as the `@Named` annotation from JSR 330.

In order to use `ParanamerParameterNameProvider`, either pass an instance when bootstrapping a
validator as shown in <<example-using-custom-parameter-name-provider>> or specify
`org.hibernate.validator.parameternameprovider.ParanamerParameterNameProvider` as value for the
`&lt;parameter-name-provider&gt;` element in the _META-INF/validation.xml_ file.


[TIP]
====
When using this parameter name provider, you need to add the Paranamer library to your classpath. It
is available in the Maven Central repository with the group id `com.thoughtworks.paranamer` and the
artifact id `paranamer`.
====

By default `ParanamerParameterNameProvider` retrieves parameter names from constants added to the byte
code at build time (via `DefaultParanamer`) and debug symbols (via `BytecodeReadingParanamer`).
Alternatively you can specify a `Paranamer` implementation of your choice when creating a
`ParanamerParameterNameProvider` instance.

[[section-constraint-definition-contribution]]
=== Providing constraint definitions

Bean Validation allows to (re-)define constraint definitions via XML in its constraint mapping
files. See <<section-mapping-xml-constraints>> for more information and <<example-constraints-car>>
for an example. While this approach is sufficient for many use cases,  it has its shortcomings
in others. Imagine for example a constraint library wanting to contribute constraint
definitions for custom types. This library could provide a mapping file with their library, but this
file still would need to be referenced by the user of the library. Luckily there are better ways.

[NOTE]
====
The following concepts are considered experimental at this time. Let us know whether you find them
useful and whether they meet your needs.
====

==== Constraint definitions via `ServiceLoader`

Hibernate Validator allows to utilize Java's
{javaApiDocsUrl}?java/util/ServiceLoader.html[ServiceLoader]
mechanism to register additional constraint definitions. All you have to do is to add the file
_javax.validation.ConstraintValidator_ to _META-INF/services_. In this service file you list the
fully qualified classnames of your constraint validator classes (one per line). Hibernate Validator
will automatically infer the constraint types they apply to.
See <<example-using-service-file-for-constraint-definitions,Constraint definition via service file>>
for an example.

[[example-using-service-file-for-constraint-definitions]]
._META-INF/services/javax.validation.ConstraintValidator_
====
[source]
----
# Assuming a custom constraint annotation @org.mycompany.CheckCase
org.mycompany.CheckCaseValidator
----
====

To contribute default messages for your custom constraints, place a file _ContributorValidationMessages.properties_
and/or its locale-specific specializations at the root of your JAR. Hibernate Validator will consider the
entries from all the bundles with this name found on the classpath in addition to those given in _ValidationMessages.properties_.

This mechanism is also helpful when creating large multi-module applications: instead of putting all the constraint
messages into one single bundle, you can have one resource bundle per module containing only those messages of that module.

[NOTE]
====
We highly recommend the reading of
http://in.relation.to/2017/03/02/adding-custom-constraint-definitions-via-the-java-service-loader/[this blog post by Marko Bekhta],
guiding you step by step through the process of creating an independent JAR that contains your custom constraints
and declares them via the `ServiceLoader`.
====

[[section-programmatic-constraint-definition]]
==== Adding constraint definitions programmatically

While the service loader approach works in many scenarios, but not in all (think for example
OSGi where service files are not visible), there is yet another way of contributing constraint
definitions. You can use the programmatic constraint declaration API - see
<<example-using-constraint-definition-api>>.

[[example-using-constraint-definition-api]]
.Adding constraint definitions through the programmatic API
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=constraintDefinition]
----
====

If your validator implementation is rather simple (i.e. no initialization from the annotation is needed,
and `ConstraintValidatorContext` is not used), you also can use this alternative API to specify the constraint logic using a Lambda expression or method reference:

[[example-using-constraint-definition-api-lambda]]
.Adding constraint definition with a Lambda expression
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=constraintDefinitionUsingLambda]
----
====

Instead of directly adding a constraint mapping to the configuration object, you may use a `ConstraintMappingContributor`
as detailed in <<section-programmatic-api-contributor>>. This can be useful when
configuring the default validator factory using _META-INF/validation.xml_ (see
<<chapter-xml-configuration>>).

[TIP]
====
One use case for registering constraint definitions through the programmatic API is the ability to specify an alternative
constraint validator for the `@URL` constraint. Historically, Hibernate Validator's default constraint
validator for this constraint uses the `java.net.URL` constructor to validate an URL.
However, there is also a purely regular expression based version available which can be configured using
a `ConstraintDefinitionContributor`:

.Using the programmatic constraint declaration API to register a regular expression based constraint definition for `@URL`
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/constraintapi/ConstraintApiTest.java[tags=urlValidationOverride]
----
====

[[section-constraint-customizing-class-loading]]
=== Customizing class-loading

There are several cases in which Hibernate Validator needs to load resources or classes given by name:

* XML descriptors (_META-INF/validation.xml_ as well as XML constraint mappings)
* classes specified by name in XML descriptors (e.g. custom message interpolators etc.)
* the _ValidationMessages_ resource bundle
* the `ExpressionFactory` implementation used for expression based message interpolation

By default, Hibernate Validator tries to load these resources via the current thread context class loader.
If that's not successful, Hibernate Validator's own class loader will be tried as a fallback.

For cases where this strategy is not appropriate (e.g. modularized environments such as OSGi),
you may provide a specific class loader for loading these resources when bootstrapping the validator factory:

[[example-using-external-class-loader]]
.Providing a class loader for loading external resources and classes
====
[source, JAVA, indent=0]
----
include::{sourcedir}/org/hibernate/validator/referenceguide/chapter12/classloading/ClassLoadingTest.java[tags=setupValidator]
----
====

In the case of OSGi, you could e.g. pass the loader of a class from the bundle bootstrapping Hibernate Validator
or a custom class loader implementation which delegates to `Bundle#loadClass()` etc.

[NOTE]
====
Call `ValidatorFactory#close()` if a given validator factory instance is not needed any longer.
Failure to do so may result in a class loader leak in cases where applications/bundles are re-deployed and a non-closed
validator factory still is referenced by application code.
====
