An Introduction to Hibernate 3 Annotations

Over the years, Hibernate has become close to the defacto standard in the world of Java database persistence. It is powerful, flexible, and boasts excellent performance. In this article, we look at how Java 5 annotations can be used to simplify your Hibernate code and make coding your persistence layer even easier.

Traditionally, Hibernate relies on external XML files for its configuration: database mappings are defined in a set of XML mapping files and loaded at startup time. There are many ways to create these mappings, either automatically, from an existing database schema or Java class model, or by hand. In any case, you can end up with a considerable number of Hibernate mapping files. Alternatively, you can use tools to generate the mapping files from javadoc-style annotations, though this adds an extra step in your build process.

In recent versions of Hibernate, a new, more elegant approach has emerged, based on Java 5 annotations. Using the new Hibernate Annotations library, you can dispense once and for all with your old mapping files--everything is defined as, you guessed it--annotations directly embedded in your Java classes. It turns out that annotations provide a powerful and flexible way of declaring persistence mappings. They are also well supported in recent Java IDEs, with automatic code completion and syntax highlighting.

Hibernate annotations also support the new EJB 3 persistence specifications. These specifications aim at providing a standardized Java persistence mechanism. While Hibernate 3 also provides a few extensions, you can quite easily stick to the standards and code your Hibernate persistence layer using the EJB 3 programming model.

Now, let's take the Hibernate Annotations through its paces.

Installing Hibernate Annotations

To use Hibernate Annotations, you will need at least Hibernate 3.2, and of course Java 5. You can download both Hibernate 3.2 and the Hibernate Annotations library from the Hibernate web site. In addition to the standard Hibernate JARs and dependencies, you will also need the Hibernate Annotations .jar file (hibernate-annotations.jar) Java Persistence API (lib/ejb3-persistence.jar). If you are using Maven, just add the corresponding dependencies into your POM file, as shown here:

The next step is to obtain a Hibernate session factory. You do this a little differently using Hibernate Annotations, though no earth-shattering modifications are necessary. You simply have to use the AnnotationConfiguration class to set up your session factory:

sessionFactory = new AnnotationConfiguration().buildSessionFactory();

As usual, you need to declare your persistence classes in the Hibernate configuration file (typically hibernate.cfg.xml), though you use the <mapping> element to declare your persistent classes:

Many Java projects these days use lightweight application frameworks such as Spring. If you are using the Spring framework, you can set up an annotation-based Hibernate session factory easily using the AnnotationSessionFactoryBean class, as shown here:

Our First Persistent Class

Now that we know how to obtain our annotation-backed Hibernate session, let's see what an annotated persistent class looks like.

Annotated persistent classes are ordinary POJOs, just like in any other Hibernate application. Well, almost. You do need to add dependencies to the Java Persistence API (javax.persistence.*), and possibly to the Hibernate Annotations packages (org.hibernate.annotations.*) if you use any Hibernate-specific extensions, but other than that, they are just ordinary POJOs with persistence-related annotations. Here's a simple example:

As we said, it's quite simple. The @Entity annotation declares the class to be persistent. The @Id annotation lets you indicate which property is the unique identifier for this class. In fact, you can either persist fields (annotating the member variables) or properties (annotating the getter methods. For the rest of this article, we will use property-based annotations. One of the nice things about annotation-based persistence is its heavy use of default values (following the "convention over configuration" mantra). For example, you don't need to declare every property to be persistent--any property will be assumed to be persistent unless you tell it otherwise by using the @Transient annotation. This simplifies your code, and also makes for a lot less typing than with the old XML mapping files.