Home > Programming / tutorials > Hibernate Tutorial – Part II

Hibernate Tutorial – Part II

Here is the first in series of hibernate tutorial. In this tutorial , you would find step by step instructions to set up hibernate with eclipse , connect with mysql database , create and run a small application . Before continuing further , we strongly recommend to go through Part 1 of tutorial.

Now we would go a little deeper inside and see how the code worked. This will help you getting a better understanding of how things work inside hibernate.

In code we didn’t actually see and Connection creation part. Hibernate automatically creates/ manages and destroys Db connection. First lets look at how Hibernate manages Connections.

Hibernate does database access using Connection pooling. Usually in plain JDBC you get connection when you want to interact with the database. But this approach is not recommended.   New connection generation always costs must in terms of server performance. The Server might get overloaded. Also maintaining idle connections will be difficult. User has to manage the database connection creation / destroy and optimization part.

It is always recommended to create database pooling, where the db connection will be created and kept ready. The java class interacting with db will pickup one , does its work and connection will be returned back to the pool. There is no overhead on developer to create and close / destroy the connection. The pooling software does everything for you.

Hibernate by default comes with c3p connection pooling software (embedded in it). C3p pooling is an open source pooling software which one can use in any java development. We can configure the c3p pool parameters like size, idle period of connection etc in the Hibernate’s configuration file itself (explained later).  But if you really don’t like pooling or not required to use pooling,  you can ignore it and configure jdbc properties for hibernate.

In the sample project explained in the first part , we mapped the contact bean to CONTACT table. It means at runtime an object of bean Contact will represent a row in the contact table.

The mapping file contact.cfg.xml was used to map the bean to table looks like below:

<?xml version=”1.0″?>

<!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd“>

<hibernate-mapping>

<class name=”Contact” table=”CONTACT”>

<id name=”id” type=”long” column=”ID” ><generator/> </id>

<property name=”firstName”>

<column name=”FIRSTNAME” />

</property>

<property name=”lastName”>

<column name=”LASTNAME”/>

</property>

<property name=”email”>

<column name=”EMAIL”/>

</property>

</class>

</hibernate-mapping>

Here we specify the class and table to be mapped to like below:

<class name=”Contact” table=”CONTACT”>

Every class will have an ID (an unique value which helps to identify a column).

The generation of ID statergy are important.(We’ll cover this later) .

We map it like below:

<id name=”id” type=”long” column=”ID” >
<generator/>
</id>

name=”id” –> property name

type=”long” à this is the hibernate type of the column. (it is not a java type). Hibernate converts the data from db and stores in bean property. This type is helpful during this phase.

column=”ID” à The db table column name to which the property is mapped.

Also we mapped other columns like below:

<property name=”firstName”>
<column name=”FIRSTNAME” />

Once we have done mapping part we can save a contact table row using an instance of Contact object.

We do this using the following code:

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

session =sessionFactory.openSession(); //Create new instance of Contact and set values in it by reading them from form object

System.out.println(”Inserting Record”);

Contact contact = new Contact();

contact.setId(3); contact.setFirstName(”Smitha”);

contact.setLastName(”Rao”); contact.setEmail(”smithaxxx@yahoo.com“);

session.save(contact);

To save Contact information we first retrieved SessionFactory and then created a Session Object. Session is a very important object of Hibernate.

Session:

This is a hibernate’s representation of a unit of work. The Session is non sharable.   This we can think as a unique window to the database through which we save and load the data into our application.  It contains the saving/loading work queued (SQL statements queued).

In code we got a Session object like below.

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();

The sessions are retrieved from instance of SessionFactory object. The Session Factory object is a Thread-Safe object, hence sharable.  The line ‘new Configuration().configure().buildSessionFactory();’ is responsible for initializing the Hibernate.

When we call new Configuration(), Hibernate searches for the file by name hibernate.properties and try to get the Configuration information and prepares for the hibernate initialization.  The location of the hibernate.properties file is important. It should be always kept in your root (or src) directory.  This properties file should contain the Hibernate properties, where one can specify the parameters like, connection pool size, the DB name, url, username, password etc.

A sample hibernate.properties file look looks below:

hibernate.connection.driver_class = org.hsqldb.jdbcDriver

hibernate.connection.url = jdbc:hsqldb:hsql://localhost

hibernate.connection.username = sa

hibernate.dialect = org.hibernate.dialect.HSQLDialect

hibernate.c3p0.min_size = 5

hibernate.c3p0.max_size = 20

hibernate.c3p0.timeout = 300

hibernate.c3p0.max_statements = 50

hibernate.c3p0.idle_test_period = 3000

hibernate.show_sql = true

hibernate.format_sql = true

 

Some of the common properties will be:

hibernate.connection.driver_class –> the driver implementation class

hibernate.connection.url –> The url to the database.

hibernate.connection.username –> username for the db access

hibernate.c3p0.min_size –> the minimum number of JDBC connections that C3P0 keeps ready at all times.

hibernate.c3p0.max_size –>This is the maximum number of connections in the pool.

hibernate.c3p0.timeout  –>You specify the timeout period (in seconds) after which an idle connection is removed from the pool.

hibernate.c3p0.max_statements –>  maximum number of prepared statements cached. Caching prepared statements actually affects the application performance.Many prepared statements can bring the performance down in some cases. So this number should be managed.

hibernate.c3p0.idle_test_period –> This is the idle time in seconds before which the db connection will be automatically validated.

All the hibernate.c3p0 properties are specific to c3p pooling. If you want to use any other pooling software, you can configure it with hibernate and specify the software specific properties.

When there is some property found in hibernate.properties file, that property will be loaded and added to the Configuration Object. If this file is not found then all the properties will be loaded with default values.

Next when you call configure ()

new Configuration().configure()

Here the file hibernate.cfg.xml file will be searched in the src folder.  At this stage the hibernate will be initialized, the table mapping xml files will be identified and the mapping to the bean and tables will be done and the SessionFactory will be created.

Hibernate.cfg.cml file is important. If you have not defined hibernate properties in the separate Hibernate.properties file, you can define them here. Also you specify other mapping xml files which map a class to a table.

If this file is not found an Exception will be thrown and the Hibernate will not be initialized. Also the location of the file should always be in the src(root) folder of your application.

a Sample hibernate.cfg.xml file looks like below:

The following is the scenario:

  1. hibernate.properties file will be searched for the hibernate configuration properties. If found the properties will be set.
  2. the properties defined in the file hibernate.cfg.xml file will be overridden by the previously defined properties.

Now lets go back to the code:

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();
//Create new instance of Contact and set values in it by reading them from form object
System.out.println(”Inserting Record”);
Contact contact = new Contact();
contact.setId(3);
contact.setFirstName(”Smitha”);
contact.setLastName(”Rao”);
contact.setEmail(”smithaxxx@yahoo.com“);
session.save(contact);

When the SessionFactory is build, all the Entity classes will be mapped. Any changes done to the mapping xml files or the entity classes will not take effect once the SessionFactory is created. ( Though you can recreate the SessionFactory object with code, we don’t recommend that and so not covering here). Thus SessionFactory will be constructed once in the lifetime of the application. So rather than keeping direct in the testing bean and initializing when testing, we can also initialize the session factory when application starts and make all other beans to use single SessionFactory.

We can define a Utility class where we can make the SessionFactory variable definition static and private and we can initialize it in the static bloc.  Something like below:

public class DbUtil{

private static SessionFactory sessionFactory;

static{

try{

sessionFactory = new Configuration.configure().buildSessionFactory();

}catch(Exception e){

throw new MyApplicationDBInitializationException(e);

}

}

public static SessionFactory getSessionFactory(){

return sessionFactory;

}

}

So our client code will be just:

session = DbUtil. getSessionFactory().openSession();
The other sequence of code are simple:

We create a contact bean and call the save method of session.

In next session we will see more about the transaction and Query objects of Hibernate.

  1. Siddhant
    June 3rd, 2014 at 06:26 | #1

    Superr explanation…It cleared my all doubts..Thanku very much..

  2. ROnak
    June 21st, 2013 at 04:03 | #2

    nice tutorial..

  3. May 28th, 2013 at 05:51 | #3

    Nice tutorial

  4. January 3rd, 2011 at 07:37 | #4

    You do not have ehcache in your classpath.

  5. Srikanth
    January 3rd, 2011 at 01:05 | #5

    hi am enclountering this EXCEPTION Plz.. Help me

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
    log4j:WARN Please initialize the log4j system properly.
    Exception in thread “main” org.hibernate.HibernateException: could not instantiate CacheProvider: org.hibernate.cache.NoCacheProvider
    at org.hibernate.cfg.SettingsFactory.createCacheProvider(SettingsFactory.java:265)
    at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:184)
    at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:1505)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1053)
    at com.lara.Client.main(Client.java:13)
    Caused by: java.lang.ClassNotFoundException: org.hibernate.cache.NoCacheProvider
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:108)
    at org.hibernate.cfg.SettingsFactory.createCacheProvider(SettingsFactory.java:262)
    … 4 more

  6. Amit
    July 21st, 2010 at 08:26 | #6

    Like the previos part … this is also useful one…Thx..!!!!

  7. July 8th, 2010 at 22:22 | #7

    @Tiiv the objective of tutorial is to explain the concept to user along with code. The focus is given on learning , not code spacing.

  8. Tiiv
    July 8th, 2010 at 14:45 | #8

    Well, good try but you have a long way in understanding the concept of a Tutorial. The most glaring issue here is syntax, and presentation. Your code is very difficult to read as you have paid no attention to how you present it, there is no replacement for good spacing tabbing and newlines. So the web remains void of a good Hibernate tutorial for beginners still

  9. Ayojava
    January 6th, 2010 at 17:35 | #9

    @Ayojava
    hello vinay,tanxs for the other time,but I ran into another issue,appreciate ur help

    -I have been able to save into the database using StoreDAO as the DAO class,but while trying to retrieve the values i get this error ..
    Exception >>>>> [Ljava.lang.Object; cannot be cast to com.Hibernate.Test.StoreDAO

    the code fragement is below:

    List listVal = listEvents(sessionFactory.getCurrentSession());
    System.out.println(“Size >>>>>>>>>>>>> ” + listVal.size());
    for (int i = 0; i < listVal.size(); i++)
    {
    StoreDAO store = (StoreDAO)listVal.get(i);
    System.out.println("City: " + store.getCity() + " State: " + store.getState());
    }

    the listevents () method :
    private static List listEvents(Session sess)
    {
    sess.beginTransaction();
    List result = sess.createSQLQuery("select * from HibernateStore").list();
    sess.beginTransaction().commit();
    return result;
    }

    why can't i cast the list object returned to the StoreDAO object?

  10. Ayojava
    January 6th, 2010 at 17:26 | #10

    hello vinay,tanxs for the other time,but I ran into another issue,appreciate ur help

    -I have been able to save into the database using StoreDAO as the DAO class,but while trying to retrieve the values i get this error ..
    Exception >>>>> [Ljava.lang.Object; cannot be cast to com.Hibernate.Test.StoreDAO

    the code fragement is below:

    List listVal = listEvents(sessionFactory.getCurrentSession());
    System.out.println(“Size >>>>>>>>>>>>> ” + listVal.size());
    for (int i = 0; i < listVal.size(); i++)
    {
    StoreDAO store = (StoreDAO)listVal.get(i);
    System.out.println("City: " + store.getCity() + " State: " + store.getState());
    }

    the listevents () method :
    private static List listEvents(Session sess)
    {
    sess.beginTransaction();
    List result = sess.createSQLQuery("select * from HibernateStore").list();
    sess.beginTransaction().commit();
    return result;
    }

    why can't i cast the list object returned to the StoreDAO object?

  11. Ayojava
    December 30th, 2009 at 16:04 | #11

    tanxs a bunch !!! its working…I missed out the tran.commit() method
    aueva i commented out the method tran.begin() was complaining that the method does not exist !!!

  12. December 29th, 2009 at 20:01 | #12

    @Ayojava

    The transaction commit statements are missing. Try this

    SessionFactory sessionFactory = new Configuration().configure()
    .buildSessionFactory();
    session = sessionFactory.openSession();

    Transaction tran = session.beginTransaction();

    tran.begin();

    // Create new instance of Contact and set values in it by reading
    // them from form object
    System.out.println(”Inserting Record”);
    Contact contact = new Contact();
    contact.setId(3);
    contact.setFirstName(”Smitha”);
    contact.setLastName(”Rao”);
    contact.setEmail(”smithaxxx@yahoo.com”);
    session.save(contact);

    tran.commit();

    System.out.println(”Done”);

    And it should work.

  13. Ayojava
    December 29th, 2009 at 16:25 | #13

    Hello,tanxs for your tutorial.I tried to modify the tutorial to work with sqlserver2005 and defining a new table,using Eclipse.pls find below a summary of the things I did..
    1- Created a storeDAO class with the ffg as variables (int storeID,storeName,storeAddress,city,state,zip).Defined the setters and getters

    2-Created a storeDAO.hbm.xml

    3-the hibernate.cfg.xml file

    com.microsoft.sqlserver.jdbc.SQLServerDriver
    ayojava
    jdbc:sqlserver://127.0.0.1:1433;database=pubs
    sa
    org.hibernate.dialect.SQLServerDialect
    true
    update

    4- Created the table
    CREATE TABLE [dbo].[HibernateStore](
    [store_ID] [int] NOT NULL,[store_Name] [varchar](50) ,[store_Address] [varchar](50),[city] [varchar](50),[state] [varchar](20),[zip] [nchar](10),
    CONSTRAINT [PK_HibernateStore] PRIMARY KEY CLUSTERED

    5- While running the code,(the src not included ,but I used the same format you’ve used) I get the printout
    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
    log4j:WARN Please initialize the log4j system properly.
    Hibernate: insert into HibernateStore (store_Name, store_Address, city, state, zip, store_ID) values (?, ?, ?, ?, ?, ?)
    Done

    However when I check the table for the values,I do not see the new values I set,so what could be wrong?

  1. October 6th, 2009 at 01:04 | #1
  2. September 28th, 2010 at 01:28 | #2
  3. October 26th, 2011 at 04:02 | #3