Validating Domain Objects in Hibernate Part 1: Introduction

Posted on September 10, 2007 by Scott Leberknight

This is the first in a series of short blogs showing how you can use Hibernate to validate your domain objects. Here I'll provide a brief introduction to validating your domain objects using Hibernate and why it matters. In future installments I'll show you how to enable the validations you apply to your domain objects, how to create your own custom validators, and provide some tips about integrating the Hibernate validator into your applications.

Every system needs data validation. In Java-based web applications using MVC frameworks like Struts, Spring MVC, or JSF, most developers simply use their framework's built-in validation scheme. Each of the aforementioned frameworks provides a way to validate form data, but this is usually restricted to the web tier. Struts provides ActionForms that have a validate() method you implement or you can use the Jakarta Commons Validator; JSF uses custom tags like <f:validateLength/> in the presentation tier; and Spring MVC has a Validator interface that can be easily plugged into Spring MVC's SimpleFormController. These solutions are either tied directly to the web tier or would require a bunch of infrastructure (or plumbing) code to make it work across all tiers seamlessly.

This is fine is many cases, but what happens when you expose functionality via a web service (I won't get into a REST vs WS-Death Star argument here, OK?) and you still need data validation? In fact usually you need the exact same validation for the domain objects. Now what? Many developers simply end up copy/pasting validation code. Ugh. Others come up with their own validation framework to keep things DRY but end up making things more complicated, plus they are writing infrastructure code instead of business logic. Along came Ruby on Rails which made it trivial to declare validation on domain objects and have that validation automatically apply no matter where the domain objects are used, i.e. in web controllers, web services, etc. This was probably most Java developers' first experience with applying validation directly to domain objects, and they were jealous (or at least I was).

Fortunately Hibernate provides the Hibernate Validator which allows you to annotate your domain objects with validation constraints. For example:

@Entity
public class User extends BaseEntity {
	
    // id, version, etc. are defined in BaseEntity
    private String userName;
    private String firstName;
    private String lastName;
    private String ssn;
	
    @Required
    @Email
    public String getUserName() { return userName; }
    public void setUserName(String userName) { this.userName = userName; }
	
    @Required
    @Length(min = 2, max = 50)
    public String getFirstName () { return firstName; }
    public void setFirstName() { this.firstName = firstName; }

    @Required
    @Length(min = 2, max = 50)
    public String getLastName () { return lastName; }
    public void setLastName() { this.lastName = lastName; }
	
    @Pattern(regex = "[0-9]{3}-[0-9]{2}-[0-9]{4}")
    public String getSsn() { return ssn; }
    public void setSsn(String ssn) { this.ssn = ssn; }
}

In the above code, we are mandating the following validation rules on all User objects:

  • User name is required and must be a well-formed email address.
  • First name is required and must be between 2 and 50 characters in length.
  • Last Name is required and must be between 2 and 50 characters in length.
  • Social Security Number is not required, but if present must match the format NNN-NN-NNNN.

With these annotations, we can now have any User object validated automatically and the same validation rules will apply no matter where the User object is used, i.e. the validation is where it should be, in the problem domain and not tied to the a specific application tier. In the next article, I'll show how to actually enable the Hibernate Validator and how to validate objects.



Post a Comment:
Comments are closed for this entry.