Sorry

A good data validation strategy is an important part of every application development project. Being able to consolidate and generalize validation using a proven framework can significantly improve the reliability of your software, especially over time.

Whereas unstructured and uncontrolled validation policies will lead to increased support and maintenance costs, a consolidated validation strategy can significantly minimize the cascade effect of changes to your code base. A validation layer can also be a very useful tool for some types of debugging.

I recently needed to implement a lightweight validation framework for a project. I discovered Hibernate Validator, an open source project from JBoss. The framework impressed me with its simplicity and flexibility, so I am introducing it with this Java Tip. I'll share my experience with setting up and using Hibernate Validator, with simple use cases that demonstrate key features such as declarative annotations, composite validation rules, and selective validation.

Data validation in Java

See Victor Okunev's "Validation with pure Java" to learn more about the java.beans package and the logic of constrained properties in Java.

Getting started with Hibernate Validator

Hibernate Validator provides a solid foundation for building lightweight, flexible validation code for Java SE and Java EE applications. Hibernate Validator is supported by a number of popular frameworks, but its libraries can also be used in a standalone implementation. Standalone Java SE validation components can become an integral part of any complex heterogeneous server-side application. In order to follow this introduction to using Hibernate Validator to build a standalone component, you will need to have JDK 6 or higher installed. All use cases in the article are built using Validator version 5.0.3. You should download the Hibernate Validator 5.0.x binary distribution package, where directory \hibernate-validator-5.0.x.Final\dist contains all the binaries required for standalone implementation.

Listing 1 shows a fragment of the Ant-built script where all binary dependencies, selected for the standalone implementation, are listed under the manifest section. The metainf section is required if externalized metadata validation will be used in the implementation. As a result of the Ant build the final JAR will reference all dependent Validator JARs through the Class-Path header of the manifest file.

Declarative annotation and constraint definition

Hibernate Validator 5.0.x is the open source reference implementation of JSR 349: Bean Validation 1.1. Declarative annotation and constraint definition are two highlights of the updated Bean Validation 1.1 framework. Expressing validation rules through a declarative syntax greatly improves the readability of the code, as shown in Listing 2.

Declarative validation on method parameters clearly define preconditions, improving the overall readability of the code. Business rules are much easier to digest because you only need to look at field, method, and class annotations. The declarative style removes the need to build a model of execution, consider state transitions, and analyze post-conditions and preconditions while learning the code.

More Hibernate annotations

Constraints can be applied to a composition of objects by using @Valid annotation. In Listing 2, @Valid is used to apply validation to a graph of dependent beans, enforcing simple validation rules and complex dependency constraints.

Listing 3. Validation rules applied to a composition of objects

Supported validation targets are not restricted to data only: it is possible to apply constraints to bean properties get methods, method parameters, and constructors.

Composite validation rules

Readability and flexibility don't always work nicely together in source code; in fact they often compete. Hibernate Validator demonstrates a setup where these two characteristics can actually complement each other. For example, Hibernate Validator supports compositions of annotations. The framework supports compositions of constraints and provides syntactical constructs representing OR, AND, and ALL_FALSE validation semantics. The OR composition offers stereotypes to skip validation on empty or null fields and is helpful when there is a need to declare validation for incomplete or optional data.

Listing 5. Declaring a validation rule where the property can be either null or a number

Classifying validation rules

Hibernate Validator lets developers classify validation rules. This means, for example, that you could associate a different runtime strategy with varying levels of failure. The framework supports an annotation payload attribute, which can be used in combination with Java marker interfaces to classify validation rules. You can also link the severity of validation failures with different levels of logging severity, where the logging strategy is configurable at runtime. Consider the simplest possible classification, where the validation rules are associated with non-recoverable errors or warnings.

Selective validation and the marker interface technique

Hibernate Validator also lets you apply validation logic selectively at runtime, adding another dimension of flexibility. This technique is helpful if the state of the system and underlying object structures goes through a well-defined set of transitions. For example, in a class hierarchy where derived classes can be in an incomplete state, while base class state has to be complete every class can be associated with a different level of validation.

Use the (groups) marker interface technique to separate validation rules into different categories. In this technique, a marker interface class is passed as a groups parameter to an annotation declaration.

If you're doing validation programmatically, the validate method of the Validator class accepts a list of marker interface classes as parameters, defining the scope of a selective validation. By default, all validation rules belong to a default validation group, which is designated by Default.class.

In Listing 10, validation is restricted to rules marked by two classes: LetterTemplateChecks and EmailLetterTemplateChecks.

Selective validation can be used as a powerful debugging technique, where only a subset of the object hierarchy has to be verified at a given time.

Externalized metadata validation

In addition to declarative annotation-based validation, the Bean Validation 1.1 specification supports a validation metadata model and programmatic validation APIs. The validation metadata model can be used as an effective control mechanism at runtime without the need to rebuild code. A variety of control mechanisms can be employed in controlling validation policies at runtime, ranging from disabling programmatically defined validation constraints to complimenting programmatically defined rules. Metadata configuration has several advanced options available. See the Hibernate Validator documentation for the complete set of options.

In order to enable metadata validation, an validation.xml file has to be available on the classpath. Constraint-mapping fields refer to XML descriptors where application-specific constraints are defined.