The Great Hibernate Tutorial – a great jump start for beginners

Hibernate has become the de-facto ORM (Object Relational Mapping) framework for most of the organizations today. It provides a very simple framework to overcome the cumbersome techniques involved with core JDBC implementations. Whenever there is a project based on database intrinsic activities it is advisable to use Hibernate than do JDBC coding. It saves a huge amount of time revolving around unnecessary chores.

Having said that, the major question which strikes anyone who does majorly JDBC is that how does a Hibernate DAO layer look like. Without looking at a practical implementation one cannot be easily convinced to work on it. This is the only compelling reason why I intended to write The Great Hibernate Tutorial.

This tutorial is aimed at those developers who want to get a quick breifing on how to implement a DAO layer using Hibernate. This tutorial does not cover the basics of ORM nor a detailed explanation of Hibernate configurations or api. It follows on the same route as the Great Ant tutorial which many readers liked.

5 Steps to Designing a DAO in Hibernate:

  1. Identify the tables which are required as entities in your project
  2. Create the Hibernate Configuration file
  3. Create the Hibernate entity mapping files (hbm) and entity classes
  4. Make the DAO layer with the required functions
  5. Test the DAO classes

Required Softwares

The versions of the various open source software’s required for the implementation are

So lets get going with the Great Hibernate Tutorial. The steps will explain you the specific details from the code while the actual code is present in the format of links at the bottom of this tutorial. You can open the links in different tabs of your browser and then start reading the tutorial for getting a better understanding.

Step 1. Identify the tables which are required as entities in your project

For the tutorial I am designing a basic Attendance System for a company which currently has only two tables Employee and Dept. If your MySQL is not setup at the moment you may visit the tutorial on how to setup Mysql in windows XP.

 
CREATE TABLE `employee` (                                                                                       
            `psno` int(11) NOT NULL default '0',                                                                          
            `name` varchar(50) default NULL,                                                                              
            `pass` varchar(50) default NULL,                                                                              
            `proj_cd` varchar(45) NOT NULL,                                                                               
            `dept_name` varchar(45) NOT NULL,                                                                             
            PRIMARY KEY  USING BTREE (`psno`),                                                                            
            KEY `FK_employee_newfk` (`proj_cd`,`dept_name`),                                                              
            CONSTRAINT `employee_ibfk_1` FOREIGN KEY (`proj_cd`, `dept_name`) REFERENCES `dept` (`PROJ_CD`, `DEPT_NAME`)  
          ) 
 
 
CREATE TABLE `dept` (                   
          `PROJ_CD` varchar(45) NOT NULL,       
          `DEPT_NAME` varchar(45) NOT NULL,     
          `START_DATE` date default NULL,       
          `TYPE` varchar(45) default NULL,      
          PRIMARY KEY  (`PROJ_CD`,`DEPT_NAME`)  
        )

The Employee and Dept have a one to many relationship. From the DDL it is evident that Dept table has composite keys. Usually composite keys are considered evil , but I am using it just for the sake of presenting a use case of configuring composite keys in hibernate.

Step 2. Create the Hibernate Configuration file

The Hibernate configuration file is where you provide all the connection level details. It is very straightforward configuration and appears similar to your JDBC connection statements. But unlike JDBC, you can specify many more things here like caching, dialects, debug queries. One important aspect of this configuration file is providing path of hbm files. Check the following two line of XML.

<mapping resource="com/abc/entities/Employee.hbm.xml"/>     
<mapping resource="com/abc/entities/Dept.hbm.xml"/>

These lines are important. They specify the paths to your entity mapping files. Entity mapping files are those XML files which tell hibernate as to how the entity classes relate to the tables. It defines how the data should flow from class properties to the table columns. But you have to be careful in mentioning the paths to the mapping files. It is not required that the files be kept in the packages as I have done but it is considered a convention.

Step 3. Create the Hibernate entity mapping files (hbm) and entity classes

In this step we would be actually defining the mapping. I have kept all the entities in the package com.abc.entities along with the mapping files. The first element is obvious <hibernate-mapping>. Within this element you would most of the times define 3 elements: Class, ID and Property.

Class – the class for which mapping to the table is being defined

<class name="com.abc.entities.Employee" table="employee" lazy="false">

One extra attribute of the element you would notice is lazy=”false”. This is the lazy loading technique of ORM the details of which are beyond the scope of this tutorial. You may even not mention it.

ID – Primary key is an absolute must in hibernate mapped tables. Primary Keys are mapped to ID as follows

<id name="psno" column="psno">
	<generator class="assigned" />
</id>

Generator means how the primary key is populated. If it was auto generated in the table then the value should have been “auto“. The value “assigned” means we will set it in the application itself. In case of Dept, since composite key exists we should define it as

<composite-id name="deptPK" class="com.abc.entities.DeptPK">
	<key-property name="projCode" column="PROJ_CD" />
	<key-property name="deptName" column="DEPT_NAME" />
</composite-id>

Property – These are columns which would be made as properties having getters and setters in the class definition

<property name="name"/>

this would map name property of Employee class to the name column of employee table.

Associations in Hibernate

The above 3 are majorly used. Apart from that you can also mention cardinality mapping if required as follows:

<many-to-one name="dept" class="com.abc.entities.Dept">
	<column name="proj_cd" not-null="true"/>
	<column name="dept_name" not-null="true"/>
</many-to-one>

Since I have a composite key in Dept table I have mentioned two columns in the above mapping. This mapping can be read as “MANY Employees are related TO ONE Dept with help of COLUMNS proj_cd and dept_name“. These mappings are called as Associations in hibernate.

In the Dept mapping file since one dept can return multiple Employees, they would be returned in the form of a set. Hence we would have to map the set of Employee as:

<set name="employees" inverse="true">
	<key>
		<column name="proj_cd"/>
		<column name="dept_name"/>
	</key>
	<one-to-many class="com.abc.entities.Employee" />
</set>

The inverse=”true” says that the association is bidirectional which is another important concept in hibernate. In a bidirectional relationship you can reach an associated element from within one element and same applies the other way too. On the contrary you may even have unidirectional relationship in which you don’t specify mapping in the other classes.

Defining Entity classes

This is straight forward. Entity classes are simple Java Beans. You can view the class definition in the links provided at the bottom of this post. A no argument public constructor is a must in case you define a custom one.

One special case here would be for composite keys. Composite keys are defined in a separate class. After this, In the class where composite keys are required you would have to make a property of the composite-class-type.

Step 4. Make the DAO layer with the required functions

Finally we are the moment of salvation. The thing which we were waiting eagerly for implementing. The DAO layer. It is always a good practice to make a separate DAO class for holding utility functions. Hibernate requires that you always open a session before accessing the database and making transactions when you update the database. This requires repeatable lines of code.

So in order to avoid repeating ourselves its better to keep these lines of code in a DAO class as shown in the links below. Check for com.abc.dao.DAO.java. You may use the class as it is since it is a routine code. For coding your own classes to make use of the utility functions in the DAO extend your class with this DAO.

Lets have a look at AdminDAO. Since I belive in interface based implementations I have provided AdminDAO as an interface and AdminDAOHibernateImpl as its implementation which extends DAO. The code is kept simple for understanding purposes. The things worth pondering are:

In functions which do an update on the tables you have to carry the following steps:

  1. begin();
  2. getSession()….; // save or update
  3. commit();
  4. rollback();ย  //in case of HibernateException and throw any custom business exception if required

For fetching data you don’t need transactions so you don’t need to do the above steps. In this case you can just execute a query via the getSession() as follows:

Query q = getSession().createQuery("from Employee e inner join fetch e.dept where e.psno = :psno");
q.setString("psno", psno.toString());
Employee emp = (Employee) q.uniqueResult();

Hibernate Query Language

The above query syntax is called HQL (Hibernate Query Language). It is syntactically very similar to JDBC with the difference that HQL queries are based on objects and not on tables so the names are case sensitive and aliases to objects are a must.

In HQL, you can either fetch a single result when you know that there would be exactly one row fetched. When you know that mutiple records might be returned then you can fetch the list as follows:

Query q = getSession().createQuery("from Employee");
List<Employee> list = q.list();
return list;

Paging in Hibernate

You can obtain paging in Hibernate very easily without any additional efforts by applying a max results criteria

q.setFirstResult(firstResult);
q.setMaxResults(maxResults);

Doesn’t it feel really good. JDBC users might feel jealous at this time1

Step 5. Test the DAO classes

Now, to our final strike. The testing can be done with POJO’s. For the tutorial I had created a service layer since I usally access teh DAO layer through the service layer. So the testing was done on the service layer instead of the DAO as this application was small. You can however test out directly the DAO functions.

static void listTest(){
	try {
		List<Employee> employees = adminService.getAllEmployees();
		for(Employee emp: employees)
			System.out.println(emp.toString());
	} catch (AppException e) {
	System.out.println(e.getMessage());
	}
}

Wasn’t that a breeze? I hope that it was. Once you gain a thorough knowledge of ORM concepts then you would appreciate working with Hibernate even more. For further knowledge, I would recommend you to go through the impedence mismatch theory to know the fundamental flaws surrounding JDBC. Working with Hibernate would then be real fun.

Enjoy folks!

Resources for the tutorial

The below files are required for running the above tutorial. Copy these to your eclipse project and add the required libraries of hibernate and mysql before running the project.

Configuration
hibernate.cfg.xml

Package: com.abc.entities
com.abc.entities.Employee.java
Employee.hbm.xml
com.abc.entities.Dept.java
com.abc.entities.DeptPK.java
Dept.hbm.xml

Package: com.abc.dao
com.abc.dao.DAO.java
com.abc.dao.AdminDAO.java
com.abc.dao.AdminDAOHibernateImpl.java

Package: com.abc.service
com.abc.service.AdminService.java
com.abc.service.AdminServiceImpl.java
com.abc.service.DeptService.java
com.abc.service.DeptServiceImpl.java

Package: com.abc.exceptions
com.abc.exceptions.AppException.java

Package: com.abc.tests
com.abc.tests.DeptTest.java

47 thoughts on “The Great Hibernate Tutorial – a great jump start for beginners

  1. I noticed few files are mssing under resource links, such as com.abc.util.SpringUtil, com.abc.dao.DeptDAO. Thanks.

  2. @sclin – Thanks for pointing it out. Actually Spring has not been used for this tutorial. I may have missed out on some code in which I had tested with Spring.

    I will correct out the article as soon as I get some time on my hands.

  3. DeptDAO missing which is a critical file for this tutorial to work.
    That means this tutorial doesnt work.
    This is the 3rd tutorial with a missing ciritical file.
    Real pro, man.

  4. Well spent a good few hours getting everything setup and went throughte tutorial, then realized this tutorial does not work because it is missing the DeptDAO and DeptDAOImpl.

    Back to searching for a working tutorial.

  5. Hi, I found this TUT very suitable for me :-), I spend long time looking for smthg like this!! But i found missing of files such as com.abc.util.SpringUtil, com.abc.dao.DeptDAO. I’m student starting learning Hibernate, please could you be so kind and send me complete eclipse project directory in any compressed format? (tar.gz, 7z, … doesn’t matter), or only missing files? Thank you very much!!!

  6. Hi,

    I liked tutorial very much. Trying to fix the missing files. I could write the DeptDAO and implementation. But couldnt write SpringUtil coz not much familiar with Spring.
    Please send me the SpringUtil and any related config file. Thanks

  7. Thanks to the various comments I was able to make the example work. I also had issues with the comment statements in the XML files. They caused parsing problems and I had to remove them. Other than that it was relatively smooth sailing.

  8. In this post I detail simple instructions for installing Glassfish v3 onto Ubuntu (although it will work just as well with Redhat, debian, and anything else). I also show how to create and deploy a simple WAR using Maven. Installing software.

  9. Nice Tutorial , but incomplete example
    There is no DeptDAO interface ,DeptDAOimpl class are missings. Also SpringUtil is also missing.
    Please update missing files .
    Thanks in advance

  10. Read it care fully he already mentioned that “quick breifing on how to implement a DAO layer using Hibernate. This tutorial does not cover the basics of ORM nor a detailed explanation of Hibernate configurations or api.”, its just an overview of hibernate that help developers to move from DAO legacy to more sophisticated persistence frame work

  11. Having said that, the major question which strikes anyone who does majorly JDBC is that how does a Hibernate DAO layer look like. Without looking at a practical implementation one cannot be easily convinced to work on it.

  12. Thank you for your great efforts. Really appreciate that. All the examples were very neat and clean and every easy to understand for a beginner on technology.

  13. I am new to hibernate, so i have started to create a sample application from online tutorial, but didnt get much idea about jar files and mapping files.

  14. Hello, looks like an impressive piece of work. But can those who have posted saying this works kindly explain how they got it to work without the missing files?

  15. You don’t test your sources. The first example fails already. Attendance System is not a good name for a database. Your first table references the second, and the script can not be run. Your outlining is badly readable.

    So you leave the impression that you are too imprecise to be trusted, and that you don’t know what you’re talking about.

    Instead please consider using this script:

    DROP database IF EXISTS attendance;
    create database attendance ;
    use attendance;

    CREATE TABLE `dept` (
    `PROJ_CD` varchar(45) NOT NULL,
    `DEPT_NAME` varchar(45) NOT NULL,
    `START_DATE` date default NULL,
    `TYPE` varchar(45) default NULL,
    PRIMARY KEY (`PROJ_CD`,`DEPT_NAME`)
    );

    CREATE TABLE `employee` (
    `psno` int(11) NOT NULL default ‘0’,
    `name` varchar(50) default NULL,
    `pass` varchar(50) default NULL,
    `proj_cd` varchar(45) NOT NULL,
    `dept_name` varchar(45) NOT NULL,
    PRIMARY KEY USING BTREE (`psno`),
    KEY `FK_employee_newfk` (`proj_cd`,`dept_name`),
    CONSTRAINT `employee_ibfk_1`
    FOREIGN KEY (`proj_cd`, `dept_name`)
    REFERENCES `dept` (`PROJ_CD`, `DEPT_NAME`)
    );

    Good luck for the rest.

  16. Suggestion:

    split your tutorial in “OLD and BAD ways” where you briefly describe composite keys and hibernate xml files,

    and a chapter “GOOD and NEW way” in which you describe hibernate annotations and synthetic id keys.

    Don’t ever call something great with this kind of quality…

  17. your hibernate xml file has a serious flaw:

    root
    admin

    this is a security problem! Don’t use this in any serious environment. You have no working experience.

  18. One extra attribute of the element you would notice is lazy=โ€falseโ€. This is the lazy loading technique of ORM the details of which are beyond the scope of this tutorial. You may even not mention it.

    so DON’t mention it! you are distracting.

  19. this tutorial is a piece of shit.

    tables are created, but it fails at *.registerxxxx(); -> Nullpointerexception

  20. THANKS
    CAN U SEND ME COMPLETE NOTES OF HIBERNATE.i want to learn this technology completely and wanted to make project in hibernate

  21. I always prefer going from domain object model to the database model, given that we’re using object-oriented modeling. I’ve seen applications that use hibernate that don’t think first in terms of objects and it seems to be less than optimal. The object model is the primary artifact and it drives the design of the database.

    Here are my steps:
    Define your object model and its relationships — inheritance, associations and parent/child with their cardinality (1-M, 1-1, etc.) and their direction (bi, uni).
    Identify those domain model objects that need to be persisted in a database and implement the database tables using the standard ways objects and their different relationships are mapped to db tables
    Define the hibernate mapping files for mapping the domain model to the database tables.
    Define your DAO classes with methods for saving, deleting, getting. updating the domain model objects; the methods will use hibernate in their implementation.

    The first 2 steps are independent of Hibernate (however, by reading hibernate documentation, it can greatly help with the understanding of defining your object model and then what the standard ways are to map an object model to a database).

    An important part of this is to make sure that you understand what the domain model is and what the other objects in your application are. The domain object model is the common ‘vocabulary’ between the non-domain model objects that are used by other layers — e.g. when the GUI calls a method on a business logic object, the parameters and return values of the business logic method are domain model objects; if that business logic class needs to call a DAO class, the parameters and return values of the DAO class are domain model objects. Therefore, the main dependency between layers is the domain model; each layer is responsible for any mapping from and to the domain model objects. Implicit in this is that you’re developing a layered architecture where your non-domain model objects are categorized into layers of abstraction that only provide the functionality that the layer specifies (e.g. the DAO layer classes only perform database access; they have no business logic, no logic to access external systems, etc.)

  22. Excellent Tutorial !

    I am also new to Hibernate and this tutorial helped me. I also agree with above comment(MetaZone)

    Can you please comment on this?

  23. What F**k ALL who are saying fantastic; GREAT and bla bla send me the running code with all files then I will believe that you are really praising this fucking tutorial !

  24. inspite of sanitary: this is showing this ASS error:
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘DeptDAO’ defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:997)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:943)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
    at com.abc.services.DeptTest.(DeptTest.java:32)
    Caused by: java.lang.ExceptionInInitializerError
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:76)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:990)
    … 13 more
    Caused by: org.hibernate.MappingException: invalid configuration
    at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2241)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:2158)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:2137)
    at com.abc.dao.DAO.(DAO.java:18)
    … 20 more
    Caused by: org.xml.sax.SAXParseException: Document is invalid: no grammar found.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.dom4j.io.SAXReader.read(SAXReader.java:465)
    at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2238)
    … 23 more
    Exception in thread “main”

Leave a Reply

Your email address will not be published. Required fields are marked *