Summary
In a recent IBM developerWorks article, Ted Bergeron claims that all layers of an enterprise application should validate input data, and that a single annotation-based validation framework for the data model can be leveraged to generate validators for every app layer.
Advertisement
Validating input data has often been a problematic part of enterprise Java applications, as Ted Bergeron points out in a recent IBM developerWorks article, Hibernate Can Meet Your Validation Needs.
The article discusses where validation should be performed, and notes that, ideally, all application layers should ensure that only valid data passes to the layer below. However, developers often don't have the time and resources to provide such a thorough approach:
Often, lead developers will forgo addressing validation in a given layer to save time, but it is debatable whether or not the drawbacks of cutting corners in this area are offset by the time savings. If the time investment needed to create and maintain validation across all application layers can be greatly reduced, the debate swings toward having validation in more layers.
The article goes on to suggest that instead of cutting corners in validation, developers can use tools that make validation in all application layers easy.
The tool the article discusses is Hibernate's validation framework. That framework allows a developer to specify validation requirements at the application model layer via annotations, and then leveraged those annotations in other application layers as well to generate the required validators.
While validation in some of those layers are handled by Hibernate automatically, other layers, such as the view, can process the model's validation-related annotations to generate, for instance, validators in the view, such as JavaScript-based validation.
The article discusses validation in the following application layers:
Model: This is where you'd apply Hibernate validation annotations.
Database: Since the database schema can be generated from the Hibernate annotations, the correct database schema will ensure that no invalid data can be entered—for instance, by not accepting null values, or by limiting field sizes to a specified length.
DAO: Depending on an application's architecture, there may be a data access layer that requires validation as well. The article notes that "Hibernate DAO implementations use the validation annotations as well, if you want them to. All you need to do is specify Hibernate event-based validation in the hibernate.cfg.xml file."
Service: The article does not discuss validation in this layer in detail, although it is evident that service-layer validators can be generated as well by processing annotations on the data model.
Controller: Validation in this layer is discussed in great detail, and the article notes that
To perform the validations, you will need to create an instance of Hibernate's ClassValidator. This class can be expensive to instantiate, so it is considered good practice to instantiate it once for each class you wish to validate. One approach is to create a utility class or a singleton storing one ClassValidator instance per model object.
View: To create validators in the view, Bergeron uses Spring MVC and JSP 2.0 tag files:
JSP 2.0 allows for custom functions to be registered in a TLD file and called in a tag file. Tag files are like taglibs but are written in JSP code, not Java code. In this way, code that is best written in the Java language can be encapsulated in functions, while code best written in JSP code can be put into the tag file. In this case, processing the annotations requires reflection, which will be performed by several functions. Code to bind to Spring or render the XHTML will be part of the tag file.
What do you think of the approach of leveraging validation metadata provided by Hibernate to generate validators in the various application layers? What tools do you currently use to provide data validation on your app layers?
To what extent, and in what different ways, do you perform validation in the each different layer? How do you feel about placing resource bundles for error messages, which really constitute user interface code, in the domain layer's validation methods so they can be reused by the controller layer?
I've been talking about this philosophy of validation for years, and I've been dreaming about a way to put my contraints in one place, and have them enforced at every level of my code. This is an excellent idea.