In this tutorial you will see how to persist the java objects using the Hibernate Object/Relational Mapping (ORM) framework. Hibernate automates ORM and considerably reduces the number of lines of code needed to persist the object in the database. This example demonstrates how to automatically generate code from the object/relational mapping file, thus saving the developers time. This helps the developers to focus on the business problem rather than doing repetitive coding work.
Hibernate uses XML document or the properties file to define the object/relational mapping. The object/relational mapping file contains the mapping between the Java object and the corresponding database table. This example illustrates how to create the ORM using the XML document.
First let‘s setup the environment. I am using
- Eclipse IDE 3.4
- Hibernate Core 3.3
- Hibernate Tools 3.2
- HSQLDB 1.8
You can download the Hibernate Core and Hibernate Tools here. HyperSQL DataBase is a 100% lightweight Java SQL Database Engine. You can download HSQLDB from this sitehttp://hsqldb.org/.
To install the Hibernate Tools, extract the HibernateTools-3.X.zip file and move all the files inside the features folder into the features folder of the eclipse installation directory and move all the files inside the plugins folder into the plugins folder of the ecilpse installation directory. Restart the eclipse.
First create a new Java project. Add the following lib files on the java build path.
antlr-2.7.6 commons-collections-3.1 dom4j-1.6.1 hibernate3 hsqldb javassist-3.4.GA jta-1.1 slf4j-api-1.5.6 slf4j-simple-1.5.6
The hibernate3.jar contains all the core hibernate files. The hsqldb.jar is used, to connect with the HSQL database, if you are using someother database then you need to include that jar file instead of this. The slf4j-api-1.5.6 jar file is used for logging the informations, you can also use other alternatives like log4j, to do that include that jar file instead of slf4j-simple-1.5.6 jar file to your classpath.
Once you have installed the hibernate tools, you will have the option to change to Hibernate prespective. Go to Window -> Open Prespective -> Other, the following dialog box appears, selectHibernate and click the Ok button.
Now let‘s see how to define the object/relational mapping using the XML document. This document has hbm.xml extension. We will now create the object/relational mapping for the simple class that holds course related details. To do that create a package com.vaannila.course in the src directory. The Hibernate XML mapping file will be created in this directory. To create the mapping file, switch to Hibernate prespective, right click the project folder and select New -> Hibernate XML Mapping File(hbm.xml)
In the pop up window select the course folder, enter the file name as Course.hbm.xml and click Next. In the next window click Finish.
Add the following code to the Course.hbm.xml file.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/ hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class"> org.hsqldb.jdbcDriver</property> <property name="hibernate.connection.url"> jdbc:hsqldb:hsql://localhost</property> <property name="hibernate.connection.username">sa</property> <property name="connection.password"></property> <property name="connection.pool_size">1</property> <property name="hibernate.dialect"> org.hibernate.dialect.HSQLDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create</property> <mapping resource="com/vaannila/course/Course.hbm.xml"/> </session-factory> </hibernate-configuration>
The hibernate-mapping element is the root element. The class element is used to map the Java class with the database table. The Java class name is specified using the name attribute of the classelement and the database table name is specified using the table attribute of the class element. Themeta element is used to create the class description. The id element is used to create the primary key. The name attribute of the id element refers to the property in the Course class and the columnattribute refers to the column in the COURSES table. The type attribute holds the hibernate mapping type, this mapping types will convert from Java to SQL data type and vice versa. Thegenerator element within the id element is used to automatically generate the primary key values. When the class attribute of the generator element is set to native, hibernate picks either identity,sequence or hilo algorithm depending upon the capabilities of the underlying database. Theproperty element is used to link a property in the Java class to a column in the database table.
The next step is to create the Hibernate configuration file. On startup, Hibernate looks for a file called hibernate.cfg.xml in the root of the classpath. To create the Hibernate Configuration File, right click the project, select New -> Hibernate Configuration File (cfg.xml)
By default the file name will be hibernate.cfg.xml, select the src directory and click Next.
Select the database dialect as HSQL. This property indicates the particular SQL variant that Hibernate generates. Select the "org.hsqldb.jdbcDriver" option for the driver class. Enter the connection url "jdbc:hsqldb:hsql://localhost". Enter the user name as "sa" and click Finish. These properties specifies the necessary configuration for the JDBC connection.
The show_sql option, if set to true will display all the executed SQL queries on the console.
The property hbm2ddl.auto, if set to create, will drop and re-create the database schema on startup.
In the end we add the Course.hbm.xml file to the configuration. The implementation of thehibernate.cfg.xml file is shown below.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/ hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class"> org.hsqldb.jdbcDriver</property> <property name="hibernate.connection.url"> jdbc:hsqldb:hsql://localhost</property> <property name="hibernate.connection.username">sa</property> <property name="connection.password"></property> <property name="connection.pool_size">1</property> <property name="hibernate.dialect"> org.hibernate.dialect.HSQLDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create</property> <mapping resource="com/vaannila/course/Course.hbm.xml"/> </session-factory> </hibernate-configuration>
Once the Hibernate configuration file is created we need to create a Hibernate console configuration. To do this right click the project folder, select New -> Hibernate Console Configuration.
The Hibernate Console configuration wizard appears.
By default the wizard will load the Hibernate configuration file information. Just click the Finishbutton to create the Hibernate console configuration.
Once the Hibernate console configuration is created, you can generate code by selecting theHibernate Code Generation Configurations option form the toolbar.
The Hibernate Code Generation wizard will be displayed. Now select the output directory as the srcdirectory.
In the Exporters tag select the "Use Java 5 Syntax" option and "Domain Code(.java)" option.
In the Refresh tab select the options as shown below and click the Run button to generate the code.
The following Course.java class will be generated from the Course.hbm.xml mapping file.
package com.vaannila.course; // Generated May 30, 2009 6:49:31 AM by Hibernate Tools 3.2.4.GA /** * This class contains the course details. * */ public class Course implements java.io.Serializable { private long courseId; private String courseName; public Course() { } public Course(String courseName) { this.courseName = courseName; } public long getCourseId() { return this.courseId; } public void setCourseId(long courseId) { this.courseId = courseId; } public String getCourseName() { return this.courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } }
Now create the HibernateUtil class. The HibernateUtil class helps in creating the SessionFactoryfrom the Hibernate configuration file. The SessionFactory is threadsafe, so it is not necessary to obtain one for each thread. Here the static singleton pattern is used to instantiate theSessionFactory. The implementation of the HibernateUtil class is shown below.
package com.vaannila.util; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure() .buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }
Now we will create a class with the main() method to run the application.
package com.vaannila.course; import java.util.List; import java.util.Iterator; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import com.vaannila.util.HibernateUtil; public class Main { public static void main(String[] args) { Main obj = new Main(); Long courseId1 = obj.saveCourse("Physics"); Long courseId2 = obj.saveCourse("Chemistry"); Long courseId3 = obj.saveCourse("Maths"); obj.listCourse(); obj.updateCourse(courseId3, "Mathematics"); obj.deleteCourse(courseId2); obj.listCourse(); } public Long saveCourse(String courseName) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; Long courseId = null; try { transaction = session.beginTransaction(); Course course = new Course(); course.setCourseName(courseName); courseId = (Long) session.save(course); transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } return courseId; } public void listCourse() { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); List courses = session.createQuery("from Course").list(); for (Iterator iterator = courses.iterator(); iterator.hasNext();) { Course course = (Course) iterator.next(); System.out.println(course.getCourseName()); } transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } } public void updateCourse(Long courseId, String courseName) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); Course course = (Course) session.get(Course.class, courseId); course.setCourseName(courseName); transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } } public void deleteCourse(Long courseId) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); Course course = (Course) session.get(Course.class, courseId); session.delete(course); transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } } }
The first call to the openSession() method begins the session. The session.beginTransaction()method is used to start a new transaction. Here we have four different methods to perform the CRUD operations.
The saveCourse() method is used to save a new Course object to the database. In thesaveCourse()method a new object of the Course class is created and the courseName value is set, thecourseId value is auto generated so the value needn‘t be set here. The session.save() method is used to persist the value in the database and once the value is saved, the id value (Primary key) is returned. Here the courseId value is of type long so we typecast the returned value to Long. Once the object is saved, the transaction is committed. If any exception occurs then the transaction is rolledback. The transaction ends either through commit or rollback action. Once the transaction ends the session is closed.
The listCourse() method is used to list all the courses. The session.createQuery() method is used to create a query object which helps in retrieving the persistant objects. Here we use Hibernate Query Language (HQL). "from Course" returns a list of all the courses in the COURSES table. Note that in the HQL we only specify the java class names and not the table names. Later, using the for loop we iterate the list of courses and display them on the console.
The updateCourse() method is used to update the course name. It takes the courseId and the newcourseName as input parameters. The courseId is used to retrive the actual course object using thesession.get() method. The session.get() method takes the class name and the id value as the input parameter and returns the corresponding Object. Here we set the new course name to the Courseobject and commit the transaction. We need not explicitly call the session.save() method to persist the object. Hibernate will automatically update the database when the state of the persistant object is modified inside a transaction. This feature of Hibernate is called automatic dirty checking.
The deleteCourse() method is used to delete a Course object. This method is similar to theupdateCourse() method, here instead of updating the object we call the session.delete() method to delete a persistant object.
The figure below shows the final directory structure of the example.
To run the example, first start the HSQLDB server. To start the HSQLDB server, run the command prompt, go to the hsqldb directory and execute the following command.
java -cp ./lib/hsqldb.jar org.hsqldb.Server
After starting the server, run the Main class. On startup the database schema will be created and the following actions will happen.
public static void main(String[] args) { Main obj = new Main(); Long courseId1 = obj.saveCourse("Physics"); Long courseId2 = obj.saveCourse("Chemistry"); Long courseId3 = obj.saveCourse("Maths"); obj.listCourse(); obj.updateCourse(courseId3, "Mathematics"); obj.deleteCourse(courseId2); obj.listCourse(); }
Each time on startup the database schema will be droped and recreated, if you want to use the existing one change the value of hbm2ddl.auto option to update.
The SQL statement generated gets displayed on the console. This is set using the show_sql option in the hibernate configuration file.
Hibernate: insert into COURSES (COURSE_ID, COURSE_NAME) values (null, ?) Hibernate: call identity() Hibernate: insert into COURSES (COURSE_ID, COURSE_NAME) values (null, ?) Hibernate: call identity() Hibernate: insert into COURSES (COURSE_ID, COURSE_NAME) values (null, ?) Hibernate: call identity() Hibernate: select course0_.COURSE_ID as COURSE1_0_, course0_.COURSE_NAME as COURSE2_0_ from COURSES course0_ Physics Chemistry Maths Hibernate: select course0_.COURSE_ID as COURSE1_0_0_, course0_.COURSE_NAME as COURSE2_0_0_ from COURSES course0_ where course0_.COURSE_ID=? Hibernate: update COURSES set COURSE_NAME=? where COURSE_ID=? Hibernate: select course0_.COURSE_ID as COURSE1_0_0_, course0_.COURSE_NAME as COURSE2_0_0_ from COURSES course0_ where course0_.COURSE_ID=? Hibernate: delete from COURSES where COURSE_ID=? Hibernate: select course0_.COURSE_ID as COURSE1_0_, course0_.COURSE_NAME as COURSE2_0_ from COURSES course0_ Physics Mathematics
Now let‘s check whether the database schema is created and the data is inserted into the COURSEStable or not. Open a new command prompt, go to the hsqldb installed directory and type the following command.
java -cp ./lib/hsqldb.jar org.hsqldb.util.DatabaseManager
The following dialog box pops up. Select the Type as "HSQL Database Engine Server" and click Ok.
The HSQL Databse Manager window opens. Here you can enter the following SQL statement, and see the data is successfully stored in the COURSES table.
To shutdown the HSQLDB properly enter "shutdown" and click the Execute button. Alternatively you can also shutdown programmatically by closing the SessionFactory, usingHibernateUtil.getSessionFactory().close() method.
You can download the source code of this example by clicking the Download link below.