Hello Hibernate
In this tutorial you will learn the basics on object/relational mapping using Hibernate.
Main Learnings
After this tutorial you will be able to:
- create an Eclipse project which uses Hibernate
- configure Hibernate to work with a relational database
- create java classes and map them to a relational database
- save objects in a relational database
- query for objects and retrieve objects from a relational database
- create an in memory database using HSQLDB
Versions used:
- OS: Windows XP Service Pack 2
- JDK 1.5.0_12
- Eclipse 3.3.0
- Hibernate Core 3.2.5
- Hibernate Annotations 3.3.0
- Hibernate Tools 3.2.0 Beta 9
- HSQLDB 1.8.0
- JUnit 4.3.1
Assumptions:
Tutorial
Welcome to the Hello Hibernate Tutorial. This tutorial requires a relational database but to avoid messy database installations we will use HSQLDB. HSQLDB is a lightweight relational database engine purely written in Java. One nice feature of HSQLDB is to create a database in memory which will make this tutorial much more easier.
As you can see in the Versions used section at the top we need a lot of software to run Hibernate. Lets get started by downloading all the stuff we need:
- Browse to the Hibernate website at http://hibernate.org.
- Go to the download section and download the binary releases (zip files) of Hibernate Core, Hibernate Annotations and Hibernate Tools.
- Extract the Core and Annotations to a location of your choice.
- As Hibernate Tools is a Eclipse Plugin we can install it by extracting the zip file to our base eclipse directory, e.g. C:\Program Files\eclipse. Don't forget to restart your Eclipse after extracting the files if your Eclipse is already open.
- Browse to the HSQLDB website at http://hsqldb.org
- Go to the download section, download the binary release and extract the zip file to a location of your choice.
Now open your Eclipse and create a new Java project with the name HelloHibernate.

To run our litte project we need to add all the required libraries to the build path. Go to the project properties click on Java Build Path in the list on the left and then click on the Libraries Tab. There you click the button Add Library... You should see something like this now:

If you have difficulties to follow these steps take a look at our Hello Waffle tutorial. There you can see how to add a user library step by step.
Lets continue with creating new user libraries for our Hibernate project. Select User Library and click on Next. In the next screen click on the User Libraries... Button.

In User Libraries click on the New... button. In the following screen enter Hibernate Core as the name for the library and hit the OK button. Select the newly created user library and click on the Add Jars... button. Browse to the folder where you have extracted the Hibernate Core and add the hibernate3.jar file.

Unfortunately Hibernate has many dependencies to 3rd party libraries so we have to add some more libraries. Select the Hibernate Core library again to add more libraries from the lib folder. We don't need all of those JARs but to keep it simple we select all JARs except for ant-1.6.5.jar and junit-3.8.1.jar as they are already provided by Eclipse. If you want to know more about the dependencies check the _README.txt in the lib folder of your Hibernate Core installation.

Now that we have added all the JARs we need for Hibernate Core we can add a new User Library. Repeat the process to create a user library with the name Hibernate Annotations. For this User Library we only need hibernate-annotation.jar which is in the base directory of Hibernate Annoations and all libraries from the lib folder. Your User Libraries should look like this now:

Puh... thats a lot of libraries but one more to go! We have to add HSQLDB as a User Library. Create a new Library with the name HSQLDB. For this one only add the hsqldb.jar from its lib folder. Now that we created all three User Libraries add all to Build Path of the HelloHibernate project.
Finally we can start writing some code. Lets start with mapping a class to the database. There are two ways in Hibernate to map a class, either by writing a XML file or use annotations. I prefer to use annotations over XML files because with XML files you have to maintain two sources and everytime you change your class you have to change the XML file as well. Take a look at the following source code:
package com.tw.hellohibernate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Greeting {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String greeting;
private Greeting() {}
public Greeting(String greeting) {
this.greeting = greeting;
}
}
To map persistent classes with Hibernate you do not have to implement any interfaces or extend your class from a base class. Hibernate allows you to map simple POJOs. The @Entity annotation defines a class as a persistent entity class and Hibernate will map it to the database. The class above has two properties: greeting holds a greeting text and id holds an unique identifer. All persistent entity classes need a unique identifier which is in general the primary key in the database. The @Id annotation is used to define the unique identifier property. Remember that a database identifier has no business meaning. To ensure equality between entity objects think about the natural key of an entity and implement equals() and hashCode() accordingly (further reading). The @GeneratedValue defines how the identifier will be generated. In our case we delegate this to the default strategy of the database and with HSQLDB this is a normal auto-increment.
We don't have to add any annotation to map the greeting property. Hibernate will automatically map every property unless you add the annotation @Transient to it. To learn more about persitent class mapping with annotations read here.
In many Hibernate tutorials available today you see a lot of Getter and Setter methods for each property in the Entity class. I don't think this is a good idea as it breaks encapsulation. Especially in case of having a Setter method for the id can be very dangerous. Only Hibernate should be responsible to set id properties.
Now that we have a persistent class we need a database to save our class. With HSQLDB we don't have to worry about setting up a database, we simply use an in memory database. To tell Hibernate which database to use we create a XML configuration file. Put this file into your base source directory:
<?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 name="helloHibernate">
<property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="hibernate.connection.url">jdbc:hsqldb:mem:testdb</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
<mapping class="com.tw.hellohibernate.Greeting"/>
</session-factory>
</hibernate-configuration>
The mem within the jdbc connection url tells HSQLDB to use an in memory database. The username sa and an empty password are the standard credentials for memory databases. For every class you want to map in this configuration you have to add a mapping tag. In our case we map the Greeting class.
Lets create a Greeting object now and save it to the database. To do that we write a small unit test:
package com.tw.hellohibernate;
import static org.junit.Assert.assertTrue;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.BeforeClass;
import org.junit.Test;
public class HelloHibernateTest {
private static Configuration hibernateConfig;
private static SessionFactory sessionFactory;
@BeforeClass
public static void initializeHibernate() {
hibernateConfig = new AnnotationConfiguration().configure();
sessionFactory = hibernateConfig.buildSessionFactory();
new SchemaExport(hibernateConfig).create(false, true);
}
@Test
public void shouldSaveGreeting() {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Greeting hello = new Greeting("hello");
session.save(hello);
tx.commit();
assertTrue(session.contains(hello));
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
throw e;
} finally {
session.close();
}
}
}
We successfully saved a Greeting object in the database. But wait! Don't we need to create a table in our database first? This is done by the SchemaExport object in the initializeHibernate() method. SchemaExport is part of Hibernate Tools and lets you create your database Schema autmatically. So before any test is run the method initializeHibernate() makes sure we read in the XML configuration file, create a SessionFactory and dumps the schema into the database. A SessionFactory serves us with Session objects which we need to perform operations on the database. In general you have only one SessionFactory object for each database in your application and this object is intended to be shared by all application threads. A Session on the other hand is intended to be a single unit of work, so don't use just one Session throughout your whole application.
Lets add a method to our test class where we query for an object an retrieve it from the database. But before that add the following equals() and hashCode() to the Greeting class:
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((greeting == null) ? 0 : greeting.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Greeting other = (Greeting) obj;
if (greeting == null) {
if (other.greeting != null)
return false;
} else if (!greeting.equals(other.greeting))
return false;
return true;
}
This is important for the next test as we test for equality between objects. Make sure to add the new method after the first test method as we retrieve the object from the first test:
@Test
public void shouldRetrieveOneGreeting() {
Session session = sessionFactory.openSession();
try {
Greeting hello = new Greeting("hello");
Query q = session.createQuery("select g from Greeting g where g.greeting=:text");
q.setString("text", "hello");
Greeting retrievedHello = (Greeting) q.uniqueResult();
assertEquals(retrievedHello, hello);
assertNotSame(retrievedHello, hello);
} catch (HibernateException e) {
throw e;
} finally {
session.close();
}
}
Hurray! We retrieved an object from the database. Notice that we did not use normal SQL to query for our object. Hibernate comes with its on object oriented query language HQL.
Summary:
This tutorial is only a brief introduction to Hibernate. I highly recommend to read through the reference documentations which comes with all Hibernate releases, as Hibernate can get quite complex very fast.
Comments (0)
You don't have permission to comment on this page.