JavaEnterprise JavaBean Validation in Hibernate and JPA 2

Bean Validation in Hibernate and JPA 2

A typical multi-tier Java application requires data validation at various layers, from the client tier to the database tier. Rather than duplicate the validation logic across all the application tiers, object relational mapping (ORM) technologies such as the Java Persistence API (JPA) and Hibernate keep the validation logic in the domain model using Bean validation (JSR-303). Bean validation specifies a metamodel and an API for validating entities, generally by using annotations that can be applied at the field, method or class level.

Specifically, the javax.validation.constraints package defines a set of built-in annotations for validation, while custom annotations can also be used to specify the constraints. Some of the standard annotations defined in this package are @NotNull, @Min, @Max, @Size and @Pattern. When constraints are applied to a class that implements an interface or extends a class, the validation is applied to its parent object as well. Here are constraints applied to a class at the field level:

import javax.validation.constraints.Min;import javax.validation.constraints.Max;import javax.validation.constraints.NotNull;import javax.validation.constraints.Size;public class Employee {   @NotNullprivate Integer id;private String fname;private String lname;@Size(min = 24, max = 30)private Integer age;@Min(1)private Integer experience;@Max(200000)private Integer salary;// other methods.}

In this article, we explain how Hibernate Validator — the reference implementation of JSR 303 — handles Bean validation and then for comparison present a brief discussion of JPA 2’s Bean validation.

Bean Validation in Action

Bean validation allows developers to validate an entire object graph by using the @Valid annotation, by which all the reference objects with @Valid get validated when the parent object is validated. With an object graph, any collection-type object also gets validated.

A developer can validate an instance by first obtaining a Validator instance, which can be obtained via ValidatorFactory as shown below:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();Validator validator = factory.getValidator();

The Validator interface contains the following methods:

  • validate() — used to validate all the constraints on the class
  • validateProperty() — used to validate the property of a given object
  • validateValue() — checks whether a single property of a class can be validated, provided the property with the specified value

Bean Validation in Hibernate

The reference implementation of JSR 303 is Hibernate Validator. The validation.xml file is read when ValidationFactory is created, and Hibernate Validator applies the configurations. Hibernate Annotations will generate the various constraints applied to its persistent classes into metadata mapping. Setting the hibernate.validator.apply_to_ddl to false disables this mapping.

For example, if the fname property of Employee is set with a constraint of @NotNull then it will be converted to its equivalent not null constraint for the corresponding column of the table in the database.

Hibernate Validator also has a built-in event listener, which is part of Hibernate Annotations, org.hibernate.cfg.beanvalidation.BeanValidationEventListener. The listener listens to events like PreInsertEvent, PreUpdateEvent and PreDeleteEvent, checks for all the constraints applied to the entities, and throws an exception when any constraints are violated.

In case of a validation failure, the information regarding the actual reason for the failure is thrown as a ConstraintViolationException that contains a collection of ConstraintViolation interface types. The reason can be determined by various methods of the ConstraintViolation interface such as getMessage(), getMessageTemplate(), etc.

By default Hibernate Annotations uses Hibernate Validator for validation if it is set in the classpath, but this can be turned off by setting the javax.persistence.validation.mode property to none. Event listeners can be set manually in the hibernate.cfg.xml file as follows:

<hibernate-configuration>    <session-factory>       ...       <property name="javax.persistence.validation.group.pre-persist">javax.validation.Default</property>       <property name="javax.persistence.validation.group.pre-update">javax.validation.Default</property>       <property name="javax.persistence.validation.group.pre-remove"></property>    </session-factory>    <event type="pre-update">       <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>    </event>    <event type="pre-insert">        <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>    </event>    <event type="pre-delete">        <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>    </event></hibernate-configuration>

Bean Validation in JPA 2

Bean validation is an optional feature in JPA 2, supported with its persistence provider. The persistence provider enables Bean validation on all entities to which annotations are applied. If Hibernate 3.5 is used as the persistence provider, then JPA 2 will use Hibernate Validator.

Event-based validation, which is performed in the hibernate.cfg.xml file in Hibernate, is configured in the persistence.xml file in JPA 2. Bean validation can be disabled by setting the validation-mode element in persistence.xml or the javax.persistence.validation.mode property to none.

Conclusion

In this article we drilled down into Bean validation in general and the reference implementation Hibernate Validator in particular, offering a brief comparison of how it is implemented in Hibernate and JPA 2.

Acknowledgements

The authors would like to sincerely thank Mr. Subrahmanya SV (VP, ECOM Research Group, E&R) for his ideas, guidance, support and constant encouragement and Ms. Mahalakshmi for kindly reviewing this article and providing valuable comments.

About the Authors

Sangeetha S. works as a Senior Technical Architect at the E-Commerce Research Labs at Infosys Technologies. She has over 10 years of experience in design and development of Java and Java EE applications. She has co-authored a book on ‘J2EE Architecture’ and also has written articles for online Java publications.

Nitin KL works at the E-Commerce Research Labs at Infosys Technologies. He is involved in design and development of Java EE applications using Hibernate, iBATIS, and JPA.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories