Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 12

Hibernate

What is Hibernate?

Hibernate is an implementation of the Java Persistence API (JPA) specification. And it is an open source
object/relational mapping frame work and makes developer life easy to connect and communicate with
different kind of relational databases in this universe.

Why do we need Hibernate?

1) Improved productivity
High-level object-oriented API
Less Java code to write
No SQL to write
ORM framework generates database-specific SQL for you

2) Improved performance :
Sophisticated caching
Eager loading
Lazy Loading

3) Improved maintainability :
A lot less code to write and It makes system more understandable and emphasizes more on business logic
rather than persistence work (SQLs)

4) Improved portability :
Switching to other SQL database requires few changes in Hibernate configuration file (Write once / run-
anywhere).

5) It reduces the traffic between business layer and data layer.

What is ORM?

ORM stands for Object Relational Mapping. And representing the relational data in the form of objects is
Called ORM

It allows a developer to map Plain Old Java Objects to relational database tables using (XML) configuration
files.
Hibernate High Level Architecture:

Hibernate Configuration:

We can configure Hibernate using configuration file hibernate.cfg.xml (or alternatively hibernate.properties ) and
mapping files *.hbm.xml And There are 2 ways to configure the Hibernate.

1) XML configuration (hibernate.cfg.xml or alternatively we can use hibernate.properties).

2) Programmatic configuration.

XML configuration (hibernate.cfg.xml or alternatively we can use hibernate.properties):

These two files are used to configure the Hibernate (connection driver class, connection URL, connection username,
connection password, dialect etc). If both files are present in the class path then hibernate.cfg.xml file overrides the
settings found in the hibernate.properties file.

hibernate.cfg.xml:

<?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">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/test
</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<mapping resource="sample/hibernate/bean/Employee.hbm.xml" />
</session-factory>
</hibernate-configuration>

Mapping files (*.hbm.xml): These files are used to map persistent objects to a relational database. It is the best
practice to store each object in an individual mapping file (i.e. mapping file per class) because storing large number of
persistent classes into one mapping file can be difficult to manage and maintain. The naming convention is to use the
same name as the persistent (POJO) class name. For example Account.class will have a mapping file named
Account.hbm.xml. Alternatively, hibernate annotations can be used as part of your persistent class code instead of the
*.hbm.xml files.

Employee.hbm.xml:

<?xml version="1.0" encoding="utf-8"?>


<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="sample.hibernate.bean.Employee" table="employee" catalog="test">
<id name="id" type="java.lang.Integer">
<column name="id" />
<!-- The <generator> element within the id element is used to automatically generate the primary key values.If we
Set the class attribute of the generator element as native to let hibernate pick up either identity, sequence or hilo
algorithm to create primary key depending upon the capabilities of the underlying database -->

<generator class="native" />


</id>
<property name="firstName" type="java.lang.String">
<column name="first_name" length="20" />
</property>
<property name="lastName" type="java.lang.String">
<column name="last_name" length="20" />
</property>
<property name="salary" type="java.lang.Integer">
<column name="salary" />
</property>
</class>
</hibernate-mapping>
Hibernate Detailed Level Architecture:

Hibernate uses various existing Java APIs, like JDBC, Java Transaction API (JTA), and Java Naming and Directory
Interface (JNDI).

JDBC allows Hibernate to connect with Database execute the dynamic SQL that it generates. JNDI and JTA allow
Hibernate to be integrated with J2EE application servers.

Configuration Object:

We use Configuration Object for configuring the Hibernate. And it searches the hibernate.cfg.xml and hibernate
mapping file (Ex., Employee.hbm.xml) and reads the information available in 2 files and stores info in memory.

SessionFactory Object:

Configuration object is used to create a SessionFactory object which intern configures Hibernate for the application
using the supplied configuration file and allows for a Session object to be instantiated. The SessionFactory is a thread
safe object and used by all the threads of an application.
The SessionFactory is heavyweight object so usually it is created during application start up and kept for later use. You
would need one SessionFactory object per database using a separate configuration file. So if you are using multiple
databases then you would have to create multiple SessionFactory objects.

Session Object:

A Session is used to get a physical connection with a database. The Session object is lightweight and designed to be
instantiated each time an interaction is needed with the database. Persistent objects are saved and retrieved through
a Session object.

The session objects should not be kept open for a long time because they are not usually thread safe and they should
be created and destroyed them as needed.

Transaction Object:

A Transaction represents a unit of work with the database and most of the RDBMS supports transaction functionality.
Transactions in Hibernate are handled by an underlying transaction manager and transaction (from JDBC or JTA).

This is an optional object and Hibernate applications may choose not to use this interface, instead managing
transactions in their own application code.

Query Object:

Query objects use SQL or Hibernate Query Language (HQL) string to retrieve data from the database and create
objects. A Query instance is used to bind query parameters, limit the number of results returned by the query, and
finally to execute the query.

Sample Snippet Code for interacting With Underlying Database:

public class HibernateUtils {

private HibernateUtils() {

}
private static SessionFactory sessionFactoryObj = null;
private static String CONFIG_FILE_LOCATION
="sample/hibernate/config/hibernate.cfg.xml";

public static synchronized final SessionFactory getSessionFactory() {


if (sessionFactoryObj == null)
sessionFactoryObj = new Configuration().configure(
CONFIG_FILE_LOCATION).buildSessionFactory();
return sessionFactoryObj;
}
}
In the above code, when new Configuration().configure(CONFIG_FILE_LOCATION) is executed, Hibernate code it
searches the hibernate.cfg.xml and hibernate mapping file (Ex., Employee.hbm.xml) and reads the information
available in 2 files and stores info in JVM memory.
When buildSessionFactory() is executed, it will get the driver class name, URL,Username, password from the JVM
memory and creates connection pool. From the connection pool, it gets one connection and establishes the
connection with database. After then, It checks whether all the tables that are mentioned in the hibernate mapping
file are available or not. If required it creates all the tables and prepares all the “CURD” queries for all the tables and
stores in the JVM’s memory.

If we mention below tag in the hibernate.cfg.xml

<property name="hbm2ddl.auto">update</property>

Hibernate code creates the tables that are mentioned in the hibernate mapping automatically.

NOTE: It is not at all recommended to call configure() and buildSessionFactory() methods repeatedly. This is why we
have to place them in Singleton design pattern like above HibernateUtils.

Session session = HibernateUtils.getSessionFactory().openSession();


Transaction tx = null;
Integer employeeID = null;
tx = (Transaction) session.beginTransaction();
Employee employee = new Employee(“Christ”, “Jesus”, 1000000);
employeeID = (Integer) session.save(employee);
tx.commit();
session.close();

When openSession() gets executed, we will get the Session Object (It is equivalent to getting Connection). And it is not
an expensive operation.When we get the Session object, internally hibernate will create a cache object and it will be
associated with Session object. This is called First Level Cache (like Hashtable).

When session.save(employee) gets executed , the hibernate code registers the employee object in First Level Cache
with registration code.

When tx.commit() gets executed, The Hibernate code checks whether there are any registered objects in First Level
Cache or not .And it now checks to which class the pojo class object is created .After then, it finds to which Table this
pojo class is mapped.

Based on registration, hibernate code picks the appropriate query from JVM’s memory. Now it gets the data from pojo
class object and replaces all ‘?’ with the values. And now sends the query to the database.

If we mention below tag in the hibernate.cfg.xml

<property name="show_sql">true</property>

It shows the SQL Query in the LOG like below.


log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into test.employee (first_name, last_name, salary) values (?, ?, ?)

How to get a record form Employee Table:

we can use either load() or get() methods of Session Object to get a record

Session session = factory.openSession();


Transaction tx = null;
tx = (Transaction) session.beginTransaction();
Employee employee = new Employee();
session.load(employee, 1);
tx.commit();
session.close();

When session.load(employee, 1) gets executed, The hibernate code checks to which Table this pojo class is mapped
and gets appropriate Select Query from JVM’s memory like below

Hibernate: select employee0_.id as id0_0_, employee0_.first_name as first2_0_0_,


employee0_.last_name as last3_0_0_, employee0_.salary as salary0_0_ from test.employee
employee0_ where employee0_.id=?

It replaces the “?” with 1 (2nd parameter of load method) and sends the query to Db.

The database will execute the query and send the resultset object to the hibernate. Now the hibernate will retrieve
the data from resultset object and place it inside the Employee pojo class object by calling setter methods. And now,
Employee pojo class object will be added to First Level Cache.

If the requested record is not available load() will return following exception.

org.hibernate.ObjectNotFoundException: No row with the given identifier exists:


[sample.hibernate.bean.Employee#3]

Session session = factory.openSession();


Transaction tx = null;
tx = (Transaction) session.beginTransaction();
Object empObj = session.get(Employee.class, 1);
tx.commit();
session.close();

When session.get(Employee.class, 1)gets executed, Whatever happens when load() gets executed,happens.

However, If the requested record is not available get() will return null
How to delete a record form Employee Table:

There are 2 approaches to delete a record.

Approach 1: In this approach, we will load the record that we would like to delete from table and then we mark that
object as to be deleted. To mark the object as “to be deleted” we use delete(object).

Session session = factory.openSession();


Transaction tx = null;
tx = (Transaction) session.beginTransaction();
Employee employee = new Employee();
session.load(employee, EmployeeID);
session.delete(employee);
tx.commit();
session.close();

When session.delete(employee)gets executed, The Employee Object is marked as to be deleted in the First Level
Cache.
When and tx.commit()gets executed, The Hibernate code checks whether there are any registered objects in First
Level Cache or not .And it now checks to which class the pojo class object is created .After then, it finds to which Table
this pojo class is mapped.

Based on registration, hibernate code picks the appropriate query from JVM’s memory. Now it gets the data from pojo
class object and replaces all ‘?’ with the values. And now sends the query to the database.

Approach 2: In this approach, we create the Employee pojo class object and pass the primary key value empID that
we would like to delete from the Employee table.And then we mark the Employee pojo class object as to be deleted
by using delete(employee).

Session session = factory.openSession();


Transaction tx = null;
tx = (Transaction) session.beginTransaction();
Employee employee = new Employee();
employee.setId(EmployeeID);
session.delete(employee);
tx.commit();
session.close();
In this approach, First hibernate checks whether the record is available or not. If it is available hibernate sends the
Delete query to DB or else we get Exception.

Hibernate: delete from test.employee where id=?


Exception in thread "main" org.hibernate.StaleStateException: Batch update returned
unexpected row count from update [0]; actual row count: 0; expected: 1

How to update a record in Employee Table:


There are 2 approaches to update a record.

Approach 1: In this approach, we will load the record that we would like to update in the table and then we change
that object with new value by calling appropriate setter method. Once If change the object , that object will be marked
as dirty object. If hibernate finds dirty objects , hibernate will issue the UPDATE query in the dirty object.

Session session = factory.openSession();


Transaction tx = null;
tx = (Transaction) session.beginTransaction();
Employee employee = (Employee) session.get(Employee.class, EmployeeID);
employee.setSalary(salary);
tx.commit();
session.close();

Hibernate: update test.employee set first_name=?, last_name=?, salary=? where id=?

Approach 2: In this approach, we have to create Employee pojo and set the details which columns need to be
updated and then pass this Employee pojo to update() method.

Session session = factory.openSession();


Transaction tx = null;
tx = (Transaction) session.beginTransaction();
Employee employee = new Employee();
employee.setId(EmployeeID);
employee.setFirstName(firstName);
employee.setLastName(lastName);
employee.setSalary(salary);
session.update(employee);
tx.commit();
session.close();

evict() and merge() Methods:

evict (employee) method is used to remove any specified object from First Level Cache
merge (employee) method is used to add any specified object to First Level Cache

Hibernate Query API’s

As part of Hibernate, They are supporting different types of Query API’s.

1) Hibernate Query Language (HQL) API


2) Criteria API
3) Native SQL API

We can use these query API’s to communicate with any relational database by using Hibernate. The Hibernate uses
Pre-defined Dialect classes (Ex. MySQLDialect) to convert Query API into corresponding SQL API.
Hibernate Query Language (HQL) API

Hibernate Query Language (HQL) is same as SQL (Structured Query Language) but it doesn't depends on the
table of the database. Instead of table name, we use class name in HQL. So it is database independent query
language.

Advantage of HQL

There are many advantages of HQL. They are as follows:

 database independent
 supports polymorphic queries
 easy to learn for Java Programmer

Query Interface

It is an object oriented representation of Hibernate Query. The object of Query can be obtained by calling the
createQuery() method Session interface.

The query interface provides many methods. There is given commonly used methods:

1. public int executeUpdate() is used to execute the update or delete query.


2. public List list() returns the result of the relation as a list.
3. public Query setFirstResult(int rowno) specifies the row number from where record will be retrieved.
4. public Query setMaxResult(int rowno) specifies the no. of records to be retrieved from the relation (table).
5. public Query setParameter(int position, Object value) it sets the value to the JDBC style query parameter.
6. public Query setParameter(String name, Object value) it sets the value to a named query parameter.

Example of HQL to get all the records

Query query=session.createQuery("from Employee"); //here persistent class name is Employee

List list=query.list();

When query.list() gets executed , list() converts HQL into corresponding SQL query. Hibernate sends SQL query to
database. The database executes the SQL query and sends Resultset Object to Hibernate. By using this Resultset
object, Hibernate stores the data in the corresponding POJO Class Objects .And then Hibernate adds all these POJO
class objects to Arraylist object.

Example of HQL to get records with pagination

Query query=session.createQuery("from Employee");

query.setFirstResult(5);
query.setMaxResult(10);

List list=query.list(); //will return the records from 5 to 10th number

Example of HQL delete query using Positional Parameters

Query query=session.createQuery("delete from Employee where id=?");

//specifying class name (Employee) not tablename

query.setParameter(0,10);

query.executeUpdate();

Similar to JDBC, In Hibernate HQL queries, we can have positional parameters.(Query with ’?’ Marks).In JDBC , the
positional parameter index starts with 1, whereas, in Hibernate, starts with 0.

Example of HQL update query using Named Queries

Transaction tx=session.beginTransaction();

Query q=session.createQuery("update Employee set firstName=:name where id=:empId");

q.setParameter("name","Varma");

q.setParameter("empId",111);

int status=q.executeUpdate();

tx.commit();

Hibernate supports Named queries. In HQL, we pass the variable names instead of “?”.
Always the named queries variables start with”:” . The Named Queries does not improve performance, but only
readability of the code.

HQL with Aggregate functions

You may call avg(), min(), max() etc. aggregate functions by HQL. Let's see some common examples:

Example to get total salary of all the employees

1. Query q=session.createQuery("select sum(salary) from Employee");


2. List<Emp> list=q.list();
3. Iterator<Emp> itr=list.iterator();
4. while(itr.hasNext()){
5. System.out.println(itr.next());
6. }

Example to get maximum salary of employee

Query q=session.createQuery("select max(salary) from Employee");

Example to get minimum salary of employee

Query q=session.createQuery("select min(salary) from Employee ");

Example to count total number of employee ID

Query q=session.createQuery("select count(id) from Employee ");

Example to get average salary of each employees

1. Query q=session.createQuery("select avg(salary) from Employee ");

You might also like