Thursday 23 August 2012

Hibernate Annotations Tutorial

  • 0
    Share
  • submit to reddit

This example is the same as the first example except that it uses annotations. There we first started by creating the .hbm.xml file, here there is no need to create it instead we will use annotations to do the object relational mapping.
In addition to the already existing jar files you need to add the following jar files to the classpath.
1.hibernate-commons-annotations.jar
2.ejb3-persistence.jar
3.hibernate-annotations.jar
Here we first start by creating the Course class. The Course class is shown below.
01.package com.vaannila.course;
02. 
03.import javax.persistence.Column;
04.import javax.persistence.Entity;
05.import javax.persistence.GeneratedValue;
06.import javax.persistence.Id;
07.import javax.persistence.Table;
08. 
09. 
10.@Entity
11.@Table(name="COURSES")
12.public class Course {
13. 
14.    private long courseId;
15.    private String courseName;
16.     
17.    public Course() {
18.    }
19.     
20.    public Course(String courseName) {
21.    this.courseName = courseName;
22.    }
23.     
24.    @Id
25.    @GeneratedValue
26.    @Column(name="COURSE_ID")
27.    public long getCourseId() {
28.        return this.courseId;
29.    }
30.     
31.    public void setCourseId(long courseId) {
32.        this.courseId = courseId;
33.    }
34.     
35.    @Column(name="COURSE_NAME", nullable=false)
36.    public String getCourseName() {
37.        return this.courseName;
38.    }
39.     
40.    public void setCourseName(String courseName) {
41.        this.courseName = courseName;
42.    }
43. 
44.}
As you can see we have used annotations in the code to do the object relational mapping. Hibernate supports EJB 3 persistence annotations. The EJB 3 annotations are contained in the javax.persistence package. If you avoid using Hibernate specific features in your application, then you will have the freedom to deploy your application in any environment that supports EJB 3. Anything imported from javax.persistence package tree is EJB 3 supported and anything imported from org.hibernate package tree is Hibernate specific.
The @Entity annotation is used to mark this class as an Entity bean. So the class should atleast have a package scope no-argument constructor.
The @Table annotation is used to specify the table to persist the data. The name attribute refers to the table name. If @Table annotation is not specified then Hibernate will by default use the class name as the table name.
The @Id annotation is used to specify the identifier property of the entity bean. The placement of the @Id annotation determines the default access strategy that Hibernate will use for the mapping. If the @Id annotation is placed over the field, then filed access will be used. Instead if it placed over the getter method of that field, then property access will be used. Here we use property access.
The @GeneratedValue annotation is used to specify the primary key generation strategy to use. If the strategy is not specified by default AUTO will be used.
The @Column annotation is used to specify the details of the column to which a field or property will be mapped. Here the courseId property is mapped to COURSE_ID column in the COURSES table. If the @Column annotation is not specified by default the property name will be used as the column name.
The next change you need to do here is, instead of adding the .hbm.xml file to the hibernate.cfg.xml file, we add the fully qualified name of the annotated class to the mapping element.
01.<?xml version="1.0" encoding="UTF-8"?>
02.<!DOCTYPE hibernate-configuration PUBLIC
03.        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
05.<hibernate-configuration>
06.    <session-factory>
07.        <property name="hibernate.connection.driver_class"> org.hsqldb.jdbcDriver</property>
08.        <property name="hibernate.connection.url"> jdbc:hsqldb:hsql://localhost<;/property>
09.        <property name="hibernate.connection.username">sa</property>
10.        <property name="connection.password"></property>
11.        <property name="connection.pool_size">1</property>
12.        <property name="hibernate.dialect"> org.hibernate.dialect.HSQLDialect</property>
13.        <property name="show_sql">true</property>
14.        <property name="hbm2ddl.auto">create</property>
15.        <mapping class="com.vaannila.course.Course" />
16.    </session-factory>
17.</hibernate-configuration>
The SessionFactory should be configured using the AnnotationConfiguration object instead of the Configuration object used with XML mappings.
01.package com.vaannila.util;
02. 
03.import org.hibernate.SessionFactory;
04.import org.hibernate.cfg.AnnotationConfiguration;
05. 
06.public class HibernateUtil {
07.    private static final SessionFactory sessionFactory;
08.    static {
09.        try {
10.            sessionFactory = new AnnotationConfiguration().configure()
11.                    .buildSessionFactory();
12.        } catch (Throwable ex) {
13.            System.err.println("Initial SessionFactory creation failed." + ex);
14.            throw new ExceptionInInitializerError(ex);
15.        }
16.    }
17. 
18.    public static SessionFactory getSessionFactory() {
19.        return sessionFactory;
20.    }
21.}
These are the only few changes you need to do to make the example work using annotations. Now the big question is should you use annotations?
If your answer is yes to the following questions then you can use annotations in your project.
  • Do you have the flexibility to use Java 5 Environment?
  • Do you have the knowledge of which production database you are going to use? If yes, you can use annotations, this brings in strong coupling. Inorder to support multiple databases, it is better to have the mapping information in a seperate xml file rather than using annotations. You can easily have multiple xml files each specific for a particular database rather than having a different sets of source codes.
Instead than keeping the mapping informations in a seperate file, using annotations you can always keep them along with the source code, in this way the soure code and mapping information will always be in sync.

No comments:

Post a Comment