100% found this document useful (1 vote)
38 views

Hibernate Tutorial

Uploaded by

Roopesh B
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
38 views

Hibernate Tutorial

Uploaded by

Roopesh B
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 251

Hibernate

About the Tutorial


Hibernate is a high-performance Object/Relational persistence and query service, which is
licensed under the open source GNU Lesser General Public License (LGPL) and is free to
download. Hibernate not only takes care of the mapping from Java classes to database
tables (and from Java data types to SQL data types), but also provides dat a query and
retrieval facilities.

This tutorial will teach you how to use Hibernate to develop your database based web
applications in simple and easy steps.

Audience
This tutorial is designed for all those Java programmers who would like to understand the
Hibernate framework and its API.

Prerequisites
We assume you have a good understanding of the Java programming language. A basic
understanding of relational databases, JDBC, and SQL will be very helpful in understanding
this tutorial.

Copyright & Disclaimer


© Copyright 2015 by Tutorials Point (I) Pvt. Ltd.

All the content and graphics published in this e-book are the property of Tutorials Point (I)
Pvt. Ltd. The user of this e-book is prohibited to reuse, retain, copy, distribute or republish
any contents or a part of the contents of this e-book in any manner without written consent
of the publisher.

We strive to update the contents of our website and tutorials as timely and as precisely as
possible, however, the contents may contain inaccuracies or errors. Tutorials Point (I) Pvt.
Ltd. provides no guarantee regarding the accuracy, timeliness, or completeness of our
website or its contents including this tutorial. If you discover any errors on our website or
in this tutorial, please notify us at [email protected]

i
Hibernate

Table of Contents
About the Tutorial ............................................................................................................... i

Audience............................................................................................................................. i

Prerequisite s ...................................................................................................................... i

Copyright & Di sclaimer....................................................................................................... i

Table of Contents .............................................................................................................. ii

1. HIBERNATE – ORM ............................................................................. 1

What is JDBC?................................................................................................................... 1

Pros and Cons of JDBC ..................................................................................................... 1

Why Object Relational Mapping (ORM)? ............................................................................ 1

What is ORM? .................................................................................................................... 3

Java ORM Frameworks ...................................................................................................... 4

2. HIBERNATE – OVERVIEW .................................................................. 5

Hibernate Advantages ....................................................................................................... 5

Supported Database s ........................................................................................................ 6

3. HIBERNATE – ARCHITECTURE ......................................................... 7

Configuration Object ......................................................................................................... 8

SessionFactory Object ...................................................................................................... 8

Session Object................................................................................................................... 8

Transaction Object ............................................................................................................ 9

Query Object...................................................................................................................... 9

Criteria Object.................................................................................................................... 9

4. HIBERNATE – ENVIRONMENT SETUP............................................ 10

Installing IDE.....................................................................................................................10

Downloading Hibernate ....................................................................................................10

Installing Hibernate...........................................................................................................11
ii
Hibernate

Verification .......................................................................................................................16

Adding Required jars to Hibernate....................................................................................17

5. HIBERNATE – CONFIGURATION ..................................................... 22

Hibernate Properties.........................................................................................................22

Hibernate with MySQL Database ......................................................................................23

6. HIBERNATE – SESSIONS ................................................................. 26

Session .............................................................................................................................26

Sample Code ....................................................................................................................26

Session Interface Methods ...............................................................................................28

7. HIBERNATE – PERSISTENT CLASS ................................................ 30

Simple POJO Example ......................................................................................................30

8. HIBERNATE – MAPPING FILES........................................................ 32

9. HIBERNATE – MAPPING TYPES ...................................................... 35

Primitive Types .................................................................................................................35

Date and Time Types ........................................................................................................35

Binary and Large Object Types.........................................................................................36

JDK-related Types ............................................................................................................36

10. HIBERNATE – EXAMPLES ................................................................ 37

Example ............................................................................................................................37

Create POJO Classe s........................................................................................................37

Create Mapping File (Employee.hbm.xml) ........................................................................39

Create Configuration File ..................................................................................................40

Persi stence Operations ....................................................................................................41

11. HIBERNATE – O/R MAPPINGS ......................................................... 48

Collection Mappings .........................................................................................................48


iii
Hibernate

Hibernate – Set Mappings .................................................................................................49

Hibernate – SortedSet Mappings ......................................................................................59

Hibernate – List Mappings ................................................................................................71

Hibernate – Bag Mappings................................................................................................81

Hibernate – Map Mappings ...............................................................................................91

Hibernate – SortedMap Mappings................................................................................... 101

Association Mappings .................................................................................................... 113

Hibernate – Many-to-One Mappings................................................................................ 113

Hibernate – One-to-One Mappings.................................................................................. 125

Hibernate – One-to-Many Mappings................................................................................ 136

Hibernate – Many-to-Many Mappings.............................................................................. 146

Inheritance Mappings ..................................................................................................... 157

Hibernate – Table Per Class Hierarchy ........................................................................... 158

Hibernate Table Per Sub-class........................................................................................ 164

Hibernate Table Per Concrete Class ............................................................................... 171

Component Mappings..................................................................................................... 177

Hibernate – Component Mappings.................................................................................. 177

12. HIBERNATE – ANNOTATIONS .......................................................189

Environment Setup for Hibernate Annotation ................................................................. 189

Annotated Class Example............................................................................................... 189

@Enti ty Annotation ......................................................................................................... 191

@Table Annotation ......................................................................................................... 191

@Id and @GeneratedValue Annotations......................................................................... 191

@Column Annotation ..................................................................................................... 192

Create Application Class ................................................................................................ 192

Database Configuration .................................................................................................. 195

Compilation and Execution............................................................................................. 196

iv
Hibernate

13. HIBERNATE – QUERY LANGUAGE ................................................198

FROM Clause .................................................................................................................. 198

AS Clause ....................................................................................................................... 198

SELECT Clause............................................................................................................... 199

WHERE Clause ............................................................................................................... 199

ORDER BY Clause .......................................................................................................... 199

GROUP by Clause ........................................................................................................... 200

Using Named Parameters ............................................................................................... 200

UPDATE Clause .............................................................................................................. 200

DELETE Clause............................................................................................................... 201

INSERT Clause................................................................................................................ 201

Aggregate Methods ........................................................................................................ 201

Pagination using Query .................................................................................................. 202

14. HIBERNATE – CRITERIA QUERIES ...............................................203

Restrictions with Criteria ................................................................................................ 203

Pagination Using Cri teria ................................................................................................ 205

Sorting the Re sults ......................................................................................................... 205

Projections & Aggregations............................................................................................ 205

Criteria Queries Example ................................................................................................ 206

Compilation and Execution............................................................................................. 212

15. HIBERNATE – NATIVE SQL ............................................................214

Scalar Queries ................................................................................................................ 214

Enti ty Queries ................................................................................................................. 214

Named SQL Queries ....................................................................................................... 214

Native SQL Example ....................................................................................................... 215

Compilation and Execution............................................................................................. 220

v
Hibernate

16. HIBERNATE – CACHING .................................................................222

First-level Cache ............................................................................................................. 222

Second-level Cache ........................................................................................................ 223

Query-level Cache........................................................................................................... 223

The Second Level Cache ................................................................................................ 223

Concurrency Strategies .................................................................................................. 223

Cache Provider ............................................................................................................... 224

The Query-level Cache.................................................................................................... 227

17. HIBERNATE – BATCH PROCESSING ............................................228

Batch Proce ssi ng Example ............................................................................................. 229

Compilation and Execution............................................................................................. 234

18. HIBERNATE – INTERCEPTORS......................................................235

How to Use Interceptors? ............................................................................................... 236

Create POJO Classe s...................................................................................................... 238

Create Database Tables .................................................................................................. 239

Create Mapping Configuration File ................................................................................. 239

Create Application Class ................................................................................................ 240

Compilation and Execution............................................................................................. 243

vi
Hibernate
1. HIBERNATE – ORM

Any enterprise application performs database operations by storing and retrieving vast
amounts of data. Despite all the available technologies for storage management ,
application developers normally struggle to perform database operations efficiently.

Generally, Java developers use lots of code or proprietary framework to interact with the
database. Therefore, it is advisable to use Object Relational Mapping (ORM) to reduct the
burden of interacting with the database. ORM forms a bridge between object models (Java
program) and relational models (database program) like JDBC.

What is JDBC?
JDBC stands for Java Database Connectivity. It provides a set of Java API for accessing
the relational databases from Java program. These Java APIs enables Java programs to
exec ute SQL statements and interact with any SQL compliant database.

JDBC provides a flexible architecture to write a database independent application that can
run on different platforms and interact with different DBMS without any modification.

Pros and Cons of JDBC


Pros of JDBC Cons of JDBC

Clean and simple SQL processing. Complex if it is used in large projects.


Good performance with large data. Large programming overhead.
Very good for small applications. No encapsulation.
Hard to implement MVC concept . Query is
Simple syntax so easy to learn.
DBMS specific .

Why Object Relational Mapping (ORM)?


When we work with an object -oriented system, there is a mismatch between the object
model and the relational database table. RDBMSs represent data in a tabular format
whereas object-oriented languages, such as Java or C# represent it as an interconnected
graph of objects.

Example
One may encounter a few problems when direct interaction takes place between object models
and relation database tables. The following example highlights the problems associated with
traditional database application structure.

Here we have a Java Class called Employee with proper constructors and associated public
functions. We have a simple java entity class for an employee having fields (variables)
such as id, first_name, last_name, and salary.

1
Hibernate

public class Employee {


private int id;
private String first_name;
private String last_name;
private int salary;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.first_name = fname;
this.last_name = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public String getFirstName() {
return first_name;
}
public String getLastName() {
return last_name;
}
public int getSalary() {
return salary;
}
}

Consider the above object needs to be stored and retrieved using the following RDBMS
table. : Following is the Create table statement for Employee class. Its field structure
should be same as the given object model (Employee class).

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

2
Hibernate

Thee following problems may arise when direction interaction takes place between object models
and relation database tables:

 First, what if we need to modify the design of our database after having developed
a few pages or our application?

 Second, loading and storing objects in a relational database exposes us to the


following five mismatch problems:

Mismatch Description
Sometimes you will have an object model, which has more classes than
Granularity
the number of corresponding tables in the database.

RDBMSs do not define anything similar to Inheritance, which is a


Inheritance
natural paradigm in object-oriented programming languages.

An RDBMS defines exactly one notion of 'sameness': the primary key.


Identity Java, however, defines both object identity (a==b) and object equality
(a.equals(b)).

Object-oriented languages represent associations using object


Associations references whereas an RDBMS represents an association as a foreign
key column.

The ways you access objects in Java and in RDBMS are fundamentally
Navigation
different.

The Object-Relational Mapping (ORM) is the solution to handle all the above impedanc e
mismatches.

What is ORM?
ORM stands for Object-Relational Mapping (ORM) is a programming technique for
converting data between relational databases and object oriented programming languages
such as Java, C#, etc.An ORM system has the following advantages over plain JDBC:

S.N. Advantages

1 Let’s business code access objects rather than DB tables.

2 Hides details of SQL queries from OO logic.

3 Based on JDBC 'under the hood.'

4 No need to deal with the database implementation.

5 Entities based on business concepts rather than database structure.

6 Transaction management and automatic key generation.

7 Fast development of application.

3
Hibernate

An ORM solution consists of the following four entities:

S.N. Solutions

1 An API to perform basic CRUD operations on objects of persistent classes.

A language or API to specify queries that refer to classes and properties of


2
classes.

3 A configurable facility for specifying mapping metadata.

A technique to interact with transactional objects to perform dirty checking, lazy


4
association fetching, and other optimization functions.

Java ORM Frameworks


There are several persistent frameworks and ORM options in Java. A persistent framew ork
is an ORM service that stores and retrieves objects into a relational database.

 Enterprise JavaBeans Entity Beans

 Java Data Objects

 Castor

 TopLink

 Spring DAO

 Hibernate, and many more

4
Hibernate
2. HIBERNATE – OVERVIEW

Hibernate is an Object-Relational Mapping(ORM) solution for JAVA. It is an open source


persistent framework created by Gavin King in 2001. It is a powerful, high performanc e
Object-Relational Persistence and Query service for any Java Application.

Hibernate maps Java classes to database tables and from Java data types to SQL data
types and relieves the developer from 95% of common data persistence related
programming tasks.

Hibernate sits between traditional Java objects and database server to handle all the works
in persisting those objects based on the appropriate O/R mechanisms and patterns.

Hibernate Advantages
Here we have listed down the advantages of using Hibernate:

 Hibernate takes care of mapping Java classes to database tables using XML files
and without writing any line of code. If there is a change in the database or in any table,
then all that you need to change are the XML file properties.

 Provides simple APIs (classes and methods) for storing and retrieving Java objects
directly to and from the database.

 Hibernate supports Inheritance , Association relations, and Collections.

 Abstracts away the unfamiliar SQL types and provides a way to work around
familiar Java Objects.

 Hibernate does not require an application server to operate.

 Hibernate Supports only unchecked exceptions, so no need to write try, catch, or throws
blocks. Generally we have a Hibernate translator which converts Checked exceptions to
Unchecked.
5
Hibernate

 Minimizes database access with smart fetching strategies.

 Hibernate has its own query language. That is Hiberate Query Language (HQL) which
contains database independent controlers.

 Manipulates Complex associations of objects of your database.

 Hibernate supports caching mechanism: It reduces the number of round trips (tr ansactions)
between an application and the database. It increases the application performance.

 Hibernate supports annotations, apart from XML. .

Supported Databases
Hibernate supports almost all the major RDBMS database servers. Following is a list of few
of the database engines that Hibernate supports:

 HSQL Database Engine

 DB2/NT

 MySQL

 PostgreSQL

 FrontBase

 Oracle

 Microsoft SQL Server Database

 Sybase SQL Server

 Informix Dynamic Server

Hibernate supports a variety of other technologies as well including:

 XDoclet Spring

 J2EE

 Eclipse plug-ins

 Maven

6
Hibernate
3. HIBERNATE – ARCHITECTURE

Hibernate has a layered architecture which helps the user to operate without having to
know the underlying APIs. Hibernate makes use of the database and configuration data to
provide persistence services (and persistent objects) to the application.

Following is a very high level view of the Hibernate Application Architecture.

Following is a detailed view of the Hibernate Application Architecture with a few important
core classes in the Hibernate layer.

7
Hibernate

Hibernate uses various existing Java APIs, like JDBC, Java Transaction API (JTA), and Java
Naming and Directory Interface (JNDI). JDBC provides a rudimentary level of abstraction
of functionality common to relational databases, allowing almost any database with a JDBC
driver to be supported by Hibernate. JNDI and JTA support Hibernate to be integrated with
J2EE application servers.

The following section gives a brief description about the class objects which are involved
in the Hibernate Layer of the given architecture diagram. This sectiong gives you a
theritical idea of how the hibernate class objects are used to build an application.

Configuration Object
Configuration is a serializable class. It is the first Hibernate object that you need to create
in any Hibernate application. It is usually created only once during application initialization.
It allows the application to specify properties and mapping documents to be used. The
Configuration object provides two keys components:

 Database Connection: A database connection is most important for Enterprise and


Database applications. It is handled through one or more configuration files supported by
Hibernate. Those are hibernate.properties file and hibernate.cfg.xml file.
 Mapping Setup: This component creates the connection between the Java classes
and database tables. It creates mapping between each entity java class and each
table in the database.

SessionFactory Object
SessionFactory is a Factory Interface used to create Session instances. After adding the
properties and Mapping files to the Configuration object, it is used to create a SessionFactory
object which in turn configures Hibernate (Front-end javaclasses and Back-end tables) for the
application. SessionFactory is a thread-safe object and used by all the threads of an application.
It is a heavyweight object, usually 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
Session is an Interface that wraps the JDBC connection. That means, it creates a physical
connection between the application and 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 Lifecycle of a Session is bounded by the beginning and end of a logical trasaction. It contains
three states:

 transient: never persistent, currently not associated with any Session.

 persistent: currently associated with unique Session.

8
Hibernate

 detached: previously persistent, currently not associated with any Session.

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

Transaction Object
Transaction is an Interface and it 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.

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

Query Object
Query is an interface and it is used in 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.

Criteria Object
Criteria is an interface and it is used for retrieving entity data by composing Criterion
(Interface) objects. Criterion Objects work like a condition (WHERE and IF) in the SQL
query, all the criterion objects (conditions) are added to the Criteria Object and that object
will be executed and used for retriving entity data in objects.

9
Hibernate
4. HIBERNATE – ENVIRONMENT SETUP

This chapter explains how to install Hibernate and other associated packages to prepare a
develop environment for Hibernate applications. We will work with MySQL database for
Hibernate examples, so make sure you already have setup for MySQL database. For more
detail on MySQL, you can check our MySQL Tutorial.

We recommend that you use an IDE for Hibernate programming. We are using Eclipse IDE
for further explanation in this tutorial.

Installing IDE
Follow the steps given below to download and install Eclipse IDE.

 Download the latest version of eclipse here.

 We are following eclipse-jee-luna-R-win32-x86_64.zip for this tutorial.

Downloading Hibernate
Make sure you already have the latest version of Java installed on your machine. Following
are the simple steps to download Hibernate on your machine.

 Make a choice whether you want to install Hibernate on Windows or Unix. Then
proceed to the next step to download either the .zip file for windows or the .tz file
for Unix.

 Download the latest version of Hibernate from here .

 At the time of writing this tutorial, I downloaded hibernate-release -


4.3.9.Final. When you unzip the downloaded file, it will produce the following
directory structure.

10
Hibernate

Installing Hibernate
Follow the instructions given below for installing Hibernate on your system. We are using
Eclipse IDE for this tutorial, therefore it is required to add Hibernate capabilities (Hibernat e
Tools) to Eclipse IDE.

Open Eclipse IDE and select Help >> Install new Software.

Once you click the new installation software option, you will find the following screenshot.
Here you will provide the URL for downloading Hibernate tools. The URL is
"http://download.jboss.org/jbosstools/updates/stable/luna/" and click the add button.

11
Hibernate

After clicking the Add button, you will find the following dialog box. Here, in the place
of Name field: Enter JBoss Tool - Eclipse. Location Field is automatically filled with the
given JBoss URL (http://download.jboss.org/jbosstools/updates/stable/luna/), otherwise
fill it. Click OK.

After clicking OK, you will find the following screenshot. Fill the following sections in the
given screenshot.

 SEC-1: This is filter section. Enter the filter text as hibernate.

 SEC-2: Here, you will find a list of hibernate tools.

12
Hibernate

 SEC-3: Click Select All for selecting all Hibernate tools provided by JBoss
organization.

Click Next to process. The process will take some time, please wait.

After completing the process, you will find the following screenshot. Here, you have to
select all the options using the Control key and click Next.

13
Hibernate

Observe the following screenshot. Here, accept the License Agreement by clicking the
radiobutton and click Finish.

14
Hibernate

After clicking the Finish button, it will display the following dialog box. It will take some
time to install the software, please wait.

After installation, you have to restart your system to save the configurations.

15
Hibernate

Verification
Follow the instructions given below to verify if the Hibernate Installation was successful or not.

Open Eclipse and go to Windows >> Open Prespective >> Others.

You will find the Hibernate Perspective in a dialog box as mentioned in the following
screenshot.

16
Hibernate

If you click Ok, then you will find the Eclipse IDE with Hibernate capabilities.

Adding Required jars to Hibernate


The following steps show how to create a Hibernate project and add the required jars to
your project. This tutorial explains the concept of Hibernate using an employee database
example. Therefore it is better to provide Employee database related names for project
variables and components.

Step 1: Create a Java Project


Open Eclipse and create a sample Java project by following the given instructions. Go
to File -> new -> Java Project. Then you will find the following screenshot, here you
need to give the project name as employee_demo and click the Finish button to create
the Java project.

17
Hibernate

Step 2: Add jars and configure the build path of your project
Right-clik on the project folder (Example_demo). Go to Build Path -> Configure Build
Path. Then you will find the following screenshot. Here click on Add External JARs for
adding the reuired jars to your project.

18
Hibernate

When you click on Add External JARs, you will find the file explorer as shown below. This
screenshot shows two important sections:

1. The address where you downloaded the Hibernate jars that we have shown in the
Downloading Hibernate section of this chapter.

2. Select all jars in the required folder. These jars are used in Hibernate programmi ng.
Click Open to add all these jars to your project.

19
Hibernate

Now, you will find all the added jars in the Libraries section. Click OK to configure the build
path for your project.

20
Hibernate

Finally, after adding all the jars to your project , the directory structure will be as shown in
the following screenshot .

We have used this project hirerarchy for the entire tutorial.


21
Hibernate
5. HIBERNATE – CONFIGURATION

Hibernate requires to know in advance — where to find the mapping information that
defines how your Java classes relate to the database tables. Hibernate also requires a set
of configuration settings to identify the respective database and mapping files. All such
information is usually supplied as a standard Java properties file called
hibernate.properties, or as an XML file named hibernate.cfg.xml.

This configuration file contains 3 types of information:

 Connection properties
 Hibernate properties
 Mapping file names

Most of the properties take their default values and it is not required to specify them in
the property file unless it is really required. This file is kept in the root directory of your
application's classpath.

Note: You must create a Configuration file for each database. Suppose you are using two
different databses like MySQL and Oracle, then you must create two configuration files.

Hibernate Properties
The following table provides a list of important properties that you will be required to
configure for a database in a standalone situation:

S.N. Properties and Description

hibernate.dialect
1 This property makes Hibernate generate the appropriate SQL for the chosen
database.

hibernate.connection.drive r_class
2
The JDBC driver class.

hibernate.connection.url
3
The JDBC URL to the database instance.

hibernate.connection.username
4
The database username.

hibernate.connection.password
5
The database password.

hibernate.connection.pool_size
6 Limits the number of connections waiting in the Hibernate database connection
pool.

hibernate.connection.autocommit
7
Allows auto-commit mode to be used for the JDBC connection.

22
Hibernate

If you are using a database along with an application server and JNDI, then you would
have to configure the following properties in the Hibernate configuration file:

S.N. Properties and Description

hibernate.connection.datasource
1
This property specifies the JNDI name defined in the application server context.

hibernate.jndi.class
2
Defines the InitialContext class for JNDI.

hibernate.jndi.<JNDIpropertyname >
3
Passes any JNDI property you like to the JNDI InitialContext.

hibernate.jndi.url
4
Provides the URL for JNDI.

hibernate.connection.username
5
Defines the database username.

hibernate.connection.password
6
Defines the database password.

Hibernate with MySQL Database


MySQL is one of the most popular open-source database systems available today. Let us
create hibernate.cfg.xml configuration file and place it in the root of your application's
classpath.

The XML configuration file must conform to the Hibernate 3 Configuration DTD, which is
available at http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd.

Example
Let us take an example for hibernate configuration file using the following properties.

 Dialect: org.hibernate,dialect.MySQLDialect

 Driver Class: com.mysql.jdbc.Driver

 Connection URL: jdbc:mysql://localhost/test

 User Nmae: root

 Password: root

 Mapping file: employee.hbm.xml

23
Hibernate

The following XML file is the Hibernate configuration file named hibernate.cfg.xml.

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


<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>

<!-- Assume test is the database name -->


<property name="hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hibernate.connection.password">
root123
</property>

<!-- List of XML mapping files -->


<mapping resource="Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

The above configuration file includes <mapping> tags, which are related to hibernate-
mapping file and we will see in next chapter what exactly a hibernate mapping file is and
how and why do we use it ?

24
Hibernate

The following table lists the Dialect properties of a few important databases:

Database Dialect Property

DB2 org.hibernate.dialect.DB2Dialect

HSQLDB org.hibernate.dialect.HSQLDialect

HypersonicSQL org.hibernate.dialect.HSQLDialect

Informix org.hibernate.dialect.InformixDialect

Ingres org.hibernate.dialect.IngresDialect

Interbase org.hibernate.dialect.InterbaseDialect

Microsoft SQL Server 2000 org.hibernate.dialect.SQLServerDialect

Microsoft SQL Server 2005 org.hibernate.dialect.SQLServer2005Dialect

Microsoft SQL Server 2008 org.hibernate.dialect.SQLServer2008Dialect

MySQL org.hibernate.dialect.MySQLDialect

Oracle (any version) org.hibernate.dialect.OracleDialect

Oracle 11g org.hibernate.dialect.Oracle10gDialect

Oracle 10g org.hibernate.dialect.Oracle10gDialect

Oracle 9i org.hibernate.dialect.Oracle9iDialect

PostgreSQL org.hibernate.dialect.PostgreSQLDialect

Progress org.hibernate.dialect.ProgressDialect

SAP DB org.hibernate.dialect.SAPDBDialect

Sybase org.hibernate.dialect.SybaseDialect

Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect

25
Hibernate
6. HIBERNATE – SESSIONS

A Session in Hibernate works like a Connection in JDBC. The session opens a single
database connection when it is created, and holds the connection until the session is
closed. Every entity class object that is loaded by Hibernate to a nd from the database
server is associated with the session.

Session
A Session is an Interface that is used to establish 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 as needed. The main function of a
Session object is to offer, create, read, and delete operations for instances of mapped
entity classes.

Instances may exist in one of the following three states at a given point in time:

 Transient: A new instance of a persistent class, which is not associated with a


Session and has no representation in the database and no identifier value is
considered transient by Hibernate.

 Persistent: You can make a transient instance persistent by associating it with a


Session. A persistent instance has a representation in the database, an identifier
value and is associated with a Session.

 Detached: Once we close the Hibernate Session, the persistent instance will
become a detached instance.

A Session is a Serializable interface, so Session instance is also serializable. The following


section explains how to create a session by gathering information from the configuration
file and maintaining transaction consistency throught out the Session. We already
disscused about confuguration file in the previous chapter.

Sample Code
In the following code snippet, the instance of a Configuration class (c) is parsing the
hibernate configuration file (hibernate.cfg.xml) to configure the hibernate application.
Using this conf information, SessionFactory (session Container) creates an instance (sf)
26
Hibernate

for this application, this instance will work throughout the application life cycle. Using this
SessionFactoy instance (sf), we can create a Session object (s) by calling
"sf.openSession();" and finally we can create a transaction object through the Session
object to maintain consistency.

/* Create confuguration object */


Configuration c=new Configuration();

/* This method reads XML document, and take the configuration information
* form "/hibernate.cfg.xml". */
c.configure("/hibernate.cfg.xml");

/* Configuration will retrieve the data written in between


* <session-factory></session-factory> tag and stores that
* information SessionFactory interface object.*/
SessionFactory sf=c.buildSessionFactory();

/* with the driver properties in sf, sf opens a DB connection.


* Session means Connection in hibernate */
Session s=sf.openSession();

/*Begins the transaction for consistency */


Transaction t=s.beginTransaction();
try {
/* Here we will create objects of Entity data class
* (means table data for dat abase) and save those objects
* using Session object (s). */

s.flush(); // execute batch statements


t.commit(); // commit the transaction
}// try
catch(Exception e) {
/* con.rollback(); */
t.rollback();
e.printStackTrace();
}
/* con.close(); */

27
Hibernate

s.close();

If the Session throws an exception, the transaction must be rolled back and the session
must be discarded.

Session Interface Methods


The Session interface provides a number of methods, but here we have listed down a few
important methods only, which we will use in this tutorial. You can check Hibernat e
documentation for a complete list of methods associated with Session and
SessionFactory.

S.N. Session Methods and Description

Transaction beginTransaction()
1
Begin a unit of work and return the associated Transaction object.
void cancelQuery()
2
Cancel the execution of the current query.
void clear()
3
Completely clear the session.
Connection close()
4
End the session by releasing the JDBC connection and cleaning up.
Criteria createCriteria(Class persistentClass)
5 Create a new Criteria instance, for the given entity class, or a superclass of an
entity class.
Criteria createCriteria(String entityName)
6
Create a new Criteria instance, for the given entity name.

Serializable getIdentifier(Object object)


7
Return the identifier value of the given entity as associated with this session.

Query createFilter(Object collection, String queryString)


8
Create a new instance of Query for the given collection and filter string.
Query createQuery(String queryString)
9
Create a new instance of Query for the given HQL query string.
SQLQuery createSQLQuery(String queryString)
10
Create a new instance of SQLQuery for the given SQL query string.
void delete(Object object)
11
Remove a persistent instance from the datastore.
void delete(String entityName, Object object)
12
Remove a persistent instance from the datastore.
Session get(String entityName, Serializable id)
13 Return the persistent instance of the given named entity with the given
identifier, or null if there is no such persistent instance.
SessionFactory getSessionFactory()
14
Get the session factory, which created this session.
void refresh(Object object)
15
Re-read the state of the given instance from the underlying database.

28
Hibernate

Transaction getTransaction()
16
Get the Transaction instance associated with this session.
boolean isConnected()
17
Check if the session is currently connected.
boolean isDirty()
18 Does this session contain any changes, which must be synchronized with the
database?
boolean isOpen()
19
Check if the session is still open.
Serializable save(Object object)
20
Persist the given transient instance, first assigning a generated identifier.
void saveOrUpdate(Object object)
21
Either save(Object) or update(Object) the given instance.
void update(Object object)
22 Update the persistent instance with the identifier of the given detached
instance.

void update(String entityName, Object object)


23 Update the persistent instance with the identifier of the given detached
instance.

29
Hibernate
7. HIBERNATE – PERSISTENT CLASS

The entire concept of Hibernate is to take the values from Java class attributes and persist
them to a database table. A mapping document helps Hibernate in determining how to
pull the values from the classes and map them with table and associated fields.

Java classes whose objects or instances will be stored in database tables are called
persistent classes in Hibernate. Hibernate works best if these classes follow some simple
rules, also known as the Plain Old Java Object (POJO) programming model.

There are following main rules of persistent classes, however, none of these rules are hard
requirements:

 All Java classes that will be persisted need a default constructor.

 All classes should contain an ID in order to allow easy identification of your objects
within Hibernate and the database. This property maps to the primary key column
of a database table.

 All attributes that will be persisted should be declared private and have get and
set methods defined in the JavaBean style.

 A central feature of Hibernate, proxies, depends upon the persistent class being
either non-final, or the implementation of an interface that declares all public
methods.

 All classes that do not extend or implement some specialized classes and interfaces
required by the EJB framework.

The POJO name is used to emphasize that a given object is an ordinary Java Object, not
a special object, and in particular not an Enterprise JavaBean.

Simple POJO Example


The following Class is a simple POJO example which is designed using the given rules.

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;

30
Hibernate

}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}

31
Hibernate
8. HIBERNATE – MAPPING FILES

Object/relational mappings are usually defined in an XML document. This mapping file
instructs Hibernate — how to map the defined class or classes to the database tables ?

Though many Hibernate users choose to write the XML code by hand, but a number of
tools exist to generate the mapping document. These include XDoclet, Middlegen, and
AndroMDA for the advanced Hibernate users.

Let us consider our previously defined POJO class whose Objects will be persisted in the
table. Let us a look into the following POJO class.

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {

32
Hibernate

return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}

There would be one table corresponding to each object you are willing to provide
persistence. Consider above objects need to be stored and retrieved into the following
RDBMS table:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Based on the two above entities, we can define following mapping file, which instructs
Hibernate how to map the defined class or classes to the database tables.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD/ /EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
33
Hibernate

<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. Let us see understand a
little detail about the mapping elements used in the mapping file:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains all the <class> elements.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds thehibernate type, this type will convert the data type from Java
to SQL.The <generator> element within the id element is used to generate the
primary key values automatically. The class attribute of the generator element is
set to native to let hibernate pick up either identity, sequence, or hilo algorit hm
to create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

There are other attributes and elements available, which will be used in a mapping
document and we will try to cover as many as possible in the subsequent chapters.

34
Hibernate
9. HIBERNATE – MAPPING TYPES

When you prepare a Hibernate mapping document, you find that you map the Java data
types into RDBMS data types. The types declared and used in the mapping files are not
Java data types; they are not SQL database types either. These types are called
Hibernate mapping types, which can translate from Java to SQL data types and vice
versa.

This chapter lists down all the basic, date and time, large object, and various other built -
in mapping types.

Primitive Types
Mapping type Java type ANSI SQL Type
integer int or java.lang.Integer INTEGER
long long or java.lang.Long BIGINT
short short or java.lang.Short SMALLINT
float float or java.lang.Float FLOAT
double double or java.lang.Double DOUBLE
big_decimal java.math.BigDecimal NUMERIC
character java.lang.String CHAR(1)
string java.lang.String VARCHAR
byte byte or java.lang.Byte TINYINT
boolean boolean or java.lang.Boolean BIT
CHAR(1) ('Y' or
yes/no boolean or java.lang.Boolean
'N')
CHAR(1) ('T' or
true/false boolean or java.lang.Boolean
'F')

Date and Time Types


ANSI SQL
Mapping type Java type
Type
date java.util.Date or java.sql.Date DATE
time java.util.Date or java.sql.Time TIME
java.util.Date or
timestamp TIMESTAMP
java.sql.Timestamp
calendar java.util.Calendar TIMESTAMP
calendar_date java.util.Calendar DATE

35
Hibernate

Binary and Large Object Types


Mapping type Java type ANSI SQL Type

VARBINARY (or
binary byte[]
BLOB)
text java.lang.String CLOB
any Java class that implements VARBINARY (or
serializable
java.io.Serializable BLOB)
clob java.sql.Clob CLOB
blob java.sql.Blob BLOB

JDK-related Types
Mapping type Java type ANSI SQL Type
class java.lang.Class VARCHAR
locale java.util.Locale VARCHAR
timezone java.util.TimeZone VARCHAR
currency java.util.Currency VARCHAR

36
Hibernate
10. HIBERNATE – EXAMPLES

Let us take an example to understand how to use Hibernate to provide Java persistence in a
standalone application. We will go through the different steps involved in creating a Java
application using Hibernate.

As we are using MySQL database for these examples, we have to add Mysql-
connector.jar to the employee_demo project in Eclipse IDE. You can download this jar
here.

Example
Let us consider employee management as an example. The employee management
system can create, update, find, and delete the records of an employee. As mentioned
above, we are using MySQL database for database operations.

The main modules for this example are as follows:

 POJOs or Model classes

Employee.java

 Mapping

Employee.hbm.xml

 Configuration

hibernate.cfg.xml

 Services

CreatingEmployee.java

UpdatingEmployee.java

FindingEmployee.java

DeletingEmployee.java

Use the same project hierarchy which we have used in the Hibernate Environment chapter.

Create POJO Classes


POJO stands for Plain Oriented Java Object which contains entities. Entities are nothing
but beans or models. In this example, we will use Employee as an entity. eid, ename,

37
Hibernate

salary, and deg are the attributes of this entity. It contains default constructor, setter
and getter methods of those attributes.

Create a package named com.tutorialspoint.hibernate.entity under src (Source)


package. Create a class named Employee.java under the given package as follows:

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
38
Hibernate

}
public void setSalary( int salary ) {
this.salary = salary;
}
}

Before going to the next module, we need to create a database for storing relational entity.
Open MySQL command line and type the following query:

create database jpadb;


use jpadb;

Create Mapping File (Employee.hbm.xml)


Mapping file plays a crucial role in Hibernate. It creates a mapping between the entity
classes and database tables. Take a look at the following XML code and compare each
entity with the above POJO class variables.

It is better to name the POJO class same as the mapping file because each POJO class
must contain one mapping file. Here we are designing the mapping file for Employee.java
so that the mapping file is named as Employee.hbm.xml.

<?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="com.tutorialspoint.hibernate.entity.Employee"
table="EMPLOYEE">
<id name="eid" type="int">
<column name="EID" />
<generator class="assigned" />
</id>
<property name="ename" type="java.lang.String">
<column name="ENAME" />
</property>
<property name="salary" type="double">
<column name="SALARY" />
</property>
<property name="deg" type="java.lang.String">

39
Hibernate

<column name="DEG" />


</property>
</class>
</hibernate-mapping>

In the above XML, the <hibernate-mapping> tag defines the mapping configuration (how
the entity class data stored into database table). The <class> tag defines entity class with
package name. The <id> tag defines the primary key of the table and the <property> tag
defines the other fields of the table.

Create Configuration File


Hibernate requires to know in advance where to find the mapping information that defines
how your Java classes relate to the database tables. Hibernate also requires a set of
configuration settings to identify the respective database and mapping files. All such
information is usually supplied as a standard Java properties file called
hibernate.properties, or as an XML file named hibernate.cfg.xml. Let us take a look
at the following code.

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


<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>

<!-- Assume test is the database name -->


<property name="hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<property name="hibernate.connection.username" >
root
</property>
<property name="hibernate.connection.password" >

40
Hibernate

root
</property>

<!-- List of XML mapping files -->


<mapping resource="employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

Persistence Operations
Persistence operations include operations such as create, read, update, and delete. In
a business component, all the persistence operations fall under service classes.

Example
Let us take an example to understand persistence operations in detail. Let us first of all
create a table called employee with the following fields – Eid, EName, Designation, and
Salary.

Eid Ename Salary Deg

1 Gopal 50000 Manager

2 kiran 40000 Writer

3 Raju 20000 Developer

4 Arshad 15000 Trainee

The operations which we will disscuss are listed below.

 Create an Employee Record: Create a table and insert into it the records of four
employees.

 Update an Employee Record: Update the salary of the employee having the id
value "1" to 60000.

 Find an Employee Record: Find and Display the details of the employee having
the id value "1".

 Delete an Employee Record: Delete the record of the employee having the id
value "1".

41
Hibernate

Create a package named com.tutorialspoint.hibe rnate.serv ice under src (source)


package. All the service classes — CreateEmloyee.java, UpdateEmployee.java,
FindEmployee.java, and DeleteEmployee.java — are under the given package.

Create Employee Record


Create an Employee class named as CreateEmployee.java as follows:

package com.tutorialspoint.hibernate.services;

import org.hibernate.cfg.*;
import org.hibernate.*;
import com.tutorialspoint.hibernate.entity.Employee;

public class CreateEmployee {


public static void main(String rags[]) throws Exception {
Configuration c=new Configuration();

/* This method reads XML document, parses */


c.configure("/hibernate.cfg.xml");

/* Configuration will retrieve the data written in between


* <session-factory> </sf> tag and stores that information
* SessionFactory interface object. */
SessionFactory sf=c.buildSessionFactory();

/* with the driver properties in sf, sf opens a DB connection.


* Session means Connection in hibernate */
Session s=sf.openSession();

/* con.setAutoCommit(false); */
Transaction t=s.beginTransaction();

try {
Employee e1= new Employee(1, "Gopal", 50000, "Manager");
Employee e2= new Employee(2, "Kiran", 40000, "Writer");
Employee e3= new Employee(3, "Raju", 20000, "Developer");

42
Hibernate

Employee e4= new Employee(4, "Arshad", 15000, "trainee");

/* All the sql queries (insert queries) add to a batch */


s.save(e1); s.save(e2); s.save(e3); s.save(e4);

/* batch of all SQL commands are now sent to


* DBstmt.executeBatch(); */
s.flush();

/* con.commit(); */
t.commit();

System.out.println("Employe records are inserted");


}
catch(Exception e) {
/* con.rollback(); */
t.rollback();
e.printStackTrace();
}
/* con.close(); */
s.close();
}
}

After compilation and execution of the above program, you will get notifications from
Hibernate library on the console panel of Eclipse IDE.

For result, open the MySQL query browser and type the following queries.

use test;
select * from employee;

The resultant database table named employee will be shown in a tabular format as
follows:

Eid Ename Salary Deg

1 Gopal 50000 Manager

2 kiran 40000 Writer

43
Hibernate

3 Raju 20000 Developer

4 Arshad 15000 Trainee

Update an Employee Record


To update an employee record, we need to get that particular record from the database,
make changes, and finally store and commit the changes. The class
named UpdateEmployee.java is as follows:

package com.tutorialspoint.hibernate.services;

import org.hibernate.*;
import org.hibernate.cfg.*;
import com.tutorialspoint.hibernate.entity.Employee;

public class UpdateEmployee {


public static void main(String rags[]) throws Exception {
Configuration c=new Configuration();
c.configure("/hibernate.cfg.xml");
SessionFactory sf=c.buildSessionFactory();
Session s=sf.openSession();
Transaction t=s.beginTransaction();

//get the particular record from database whose having eid = 1


Employee e1=(Employee)s.get(Employee.class,new Integer(1));

//Update his salary to 60000


e1.setSalary(60000);
s.update(e1);
s.flush();
t.commit();
s.close();
}
}

After compilation and execution of the above program, you will get notifications from the
Hibernate library on the console panel of Eclipse IDE.

For result, open the MySQL query browser and type the following queries.
44
Hibernate

use test;
select * from employee;

The resultant database table named employee will be shown in a tabular format as
follows:

Eid Ename Salary Deg

1 Gopal 60000 Manager

2 kiran 40000 Writer

3 Raju 20000 Developer

4 Arshad 15000 Trainee

The salary of employee 1 is updated to 60000.

Find an Employee Record


Now let us see how to find the record of an employee and display it. This is a read-only
operation, hence there is no need to commit. The class named FindEmployee.java is as
follows.

package com.tutorialspoint.hibernate.services;

import org.hibernate.*;
import org.hibernate.cfg.*;
import com.tutorialspoint.hibernate.entity.Employee;

public class FindEmployee {


public static void main(String rags[]) throws Exception {
Configuration c=new Configuration();
c.configure("/hibernate.cfg.xml");
SessionFactory sf=c.buildSessionFactory();
Session s=sf.openSession();

//get the particular record from database whose having eid = 1


Employee e1=(Employee)s.get(Employee.class,new Integer(1));

System.out.println("employee ID = " + e1.getEid( ));


45
Hibernate

System.out.println("employee NAME = " + e1.getEname( ));


System.out.println("employee SALARY = " + e1.getSalary( ));
System.out.println("employee DESIGNATION = " + e1.getDeg( ));
s.close();
}
}

After compilation and execution of the above program, you will get output from Hibernat e
library on the console panel of Eclipse IDE as follows:

employee ID = 1
employee NAME = Gopal
employee SALARY = 46000.0
employee DESIGNATION = Technical Manager

Delete an Employee Record


To delete the record of an Employee, we will first get the record and then delete it. Here
Transaction plays an important role.

The class named DeleteEmployee.java as follows:

package com.tutorialspoint.hibernate.services;

import org.hibernate.*;
import org.hibernate.cfg.*;
import com.tutorialspoint.hibernate.entity.Employee;

public class DeleteEmployee {


public static void main(String rags[]) throws Exception {
Configuration c=new Configuration();
c.configure("/hibernate.cfg.xml");
SessionFactory sf=c.buildSessionFactory();
Session s=sf.openSession();
Transaction t=s.beginTransaction();

//get the particular record from database whose having eid = 1


Employee e1=(Employee)s.get(Employee.class,new Integer(1));

46
Hibernate

//delete the record object


s.delete(e1);
t.commit();
s.close();
}
}

After compilation and execution of the above program, you will get notifications from
Hibernate library on the console panel of eclipse IDE.

For result, open the MySQL query browser and type the following queries.

use test;
select * from employee;

The resultant database table named employee will be shown in a tabular format as
follows:

Eid Ename Salary Deg

2 kiran 40000 Writer

3 Raju 20000 Developer

4 Arshad 15000 Trainee

The employee record, whose Eid = 1 was removed from database table.

47
Hibernate
11. HIBERNATE – O/R MAPPINGS

So far, we have seen very basic O/R mapping using hibernate, but there are four most
important mapping topics, which we have to learn in detail.

These are:

 Collection Mappings.

 Association Mappings.

 Inheritance Mappings.

 Component Mappings.

Collection Mappings
If an entity or class has collection of values for a particular variable, then we can map
those values using any one of the collection interfaces available in java. Hibernate can
persist instances of java.util.Map, java.util.Set, java.util.SortedMa p,
java.util.SortedSet, java.util.List, and any array of persistent entities or values.

Collection type Mapping and Description


This is mapped with a <set> element and initialized
java.util.Set
with java.util.HashSet

This is mapped with a <set> element and initialized


java.util.SortedSet with java.util.TreeSet. The sort attribute can be set to
either a comparator or natural ordering.

This is mapped with a <list> element and initialized


java.util.List
with java.util.ArrayList
This is mapped with a <bag> or <ibag> element and
java.util.Collection
initialized with java.util.ArrayList
This is mapped with a <map> element and initialized
java.util.Map
with java.util.HashMap

This is mapped with a <map> element and initialized


java.util.SortedMap with java.util.TreeMap. The sort attribute can be set to
either a comparator or natural ordering.

Arrays are supported by Hibernate with <primitive-array> for Java primitive value types
and <array> for everything else. However, they are rarely used, so I am not going to
discuss them in this tutorial.

48
Hibernate

If you want to map a user defined collection interfaces, which is not directly supported by
Hibernate, you need to tell Hibernate about the semantics of your custom collections,
which is not very easy and not recommend to be used.

Hibernate – Set Mappings


A Set is a java collection that does not contain any duplicate element. More formally, sets
contain no pair of elements e1 and e2 such that e1.equals(e2), and at most , one null
element. So, objects to be added to a set must implement both the equals() and
hashCode() methods so that Java can determine whether any two elements/objects are
identical.

A Set is mapped with a <set> element in the mapping table and initialized with
java.util.HashSet. You can use Set collection in your class when there is no duplicate
element required in the collection.

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table ,
which would have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Further, assume each employee can have one or more certificate associated with him/her.
So, we will store certificate related information in a separate table having the following
structure:

create table CERTIFICATE (


id INT NOT NULL auto_increment,
certificate_name VARCHAR(30) default NULL,
employee_id INT default NULL,
PRIMARY KEY (id)
);

There will be one-to-many relationship between EMPLOYEE and CERTIFICATE objects:

Define POJO Classes


Let us implement our POJO class Employee, which will be used to persist the objects
related to EMPLOYEE table and having a collection of certificates in Set variable.
49
Hibernate

import java.util.*;

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;
private Set certificates;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
50
Hibernate

public void setSalary( int salary ) {


this.salary = salary;
}

public Set getCertificates() {


return certificates;
}
public void setCertificates( Set certificates ) {
this.certificates = certificates;
}
}

Now let us define another POJO class corresponding to CERTIFICATE table so that
certificate objects can be stored and retrieved into the CERTIFICATE table. This class
should also implement both the equals() and hashCode() methods so that Java can
determine whether any two elements/objects are identical.

public class Certificate {


private int id;
private String name;
public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public boolean equals(Object obj) {
if (obj == null) return false;
51
Hibernate

if (!this.getClass().equals(obj.getClass())) return false;

Certificate obj2 = (Certificate)obj;


if((this.id == obj2.getId()) && (this.name.equals(obj2.getName())))
{
return true;
}
return false;
}
public int hashCode() {
int tmp = 0;
tmp = ( id + name ).hashCode();
return tmp;
}
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate how to map the defined classes
to the database tables. The <set> element will be used to define the rule for Set collection
used.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<set name="certificates" cascade="all">
<key column="employee_id"/>

52
Hibernate

<one-to-many class="Certificate"/>
</set>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>

<class name="Certificate" table="CERTIFICATE">


<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

53
Hibernate

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. T he
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <set> element is new here and has been introduced to set the relationship
between Certificate and Employee classes. We used the cascade attribute in the
<set> element to tell Hibernate to persist the Certificate objects at the same time
as the Employee objects. The name attribute is set to the defined Set variable in
the parent class, in our case, it is certificates. For each set variable, we need to
define a separate set element in the mapping file.

 The <key> element is the column in the CERTIFICATE table that holds the foreign
key to the parent object i.e. table EMPLOYEE.

 The <one-to-many> element indicates that one Employee object relates to many
Certificate objects and, as such, the Certificate object must have a n Employee
parent associated with it. You can use either <one-to-one>, <many-to-one> or
<many-to-many> elements based on your requirement.

CreateApplication Class
Finally, we will c reate our application class with the main() method to run the application.
We will use this application to save few Employees’ records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();
54
Hibernate

/* Let us have a set of certificates for the first employee */


HashSet set1 = new HashSet();
set1.add(new Certificate("MCA"));
set1.add(new Certificate("MBA"));
set1.add(new Certificate("PMP"));

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

/* Another set of certificates for the second employee */


HashSet set2 = new HashSet();
set2.add(new Certificate("BCA"));
set2.add(new Certificate("BA"));

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down all the employees */


ME.listEmployees();

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, Set cert){
Session session = factory.openSession();
Transaction tx = null;
55
Hibernate

Integer employeeID = null;


try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
Set certificates = employee.getCertificates();
for (Iterator iterator2 =
certificates.iterator(); iterator2.hasNext();){
Certificate certName = (Certificate) iterator2.next();
System.out.println("Certificate: " + certName.getName());
}
}
56
Hibernate

tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
57
Hibernate

}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above application using Eclipse IDE. Make
sure that all the required jars are added to the project . Create hibernate.cfg.xml
configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Certificate.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute Manage Employee binary to run the program.

You would get some notifications from Hibernate Library on the screen. And at the same
time, records would be created in EMPLOYEE and CERTIFICATE tables.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Certificate: MBA
Certificate: PMP
Certificate: MCA
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MBA
Certificate: PMP
Certificate: MCA

58
Hibernate

If you check your EMPLOYEE and CERTIFICATE tables, they should have the following
records:

mysql> select * from employee;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 1 | Manoj | Kumar | 5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

mysql> select * from certificate;


+----+------------------+-------------+
| id | certificate_name | employee_id |
+----+------------------+-------------+
| 1 | MBA | 1 |
| 2 | PMP | 1 |
| 3 | MCA | 1 |
+----+------------------+-------------+
3 rows in set (0.00 sec)

mysql>

Hibernate – SortedSet Mappings


A SortedSet is a java collection that does not contain any duplicate element and element s
are ordered using their natural ordering or by a comparator provided.

A SortedSet is mapped with a <set> element in the mapping table and initialized with
java.util.TreeSet. The sort attribute can be set to either a comparator or natural ordering.
If we use natural ordering, then its iterator will traverse the set in ascending element
order.

Define RDBMS Tables


Consider a situation where we need to store our employee records in the EMPLOYEE table,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,

59
Hibernate

last_name VARCHAR(20) default NULL,


salary INT default NULL,
PRIMARY KEY (id)
);

Further, assume each employee can have one or more certificate associated with him/her.
So, we will store certificate related information in a separate table having the following
structure:

create table CERTIFICATE (


id INT NOT NULL auto_increment,
certificate_name VARCHAR(30) default NULL,
employee_id INT default NULL,
PRIMARY KEY (id)
);

There will be one-to-many relationship between EMPLOYEE and CERTIFICATE objects:

Define POJO Classes


Let us implement our POJO class Employee, which will be used to persist the objects
related to EMPLOYEE table and having a collection of certificate s in SortedSet variable.

import java.util.*;

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;
private SortedSet certificates;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;

60
Hibernate

}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
public SortedSet getCertificates() {
return certificates;
}
public void setCertificates( SortedSet certificates ) {
this.certificates = certificates;
}
}

Now let us define another POJO class corresponding to CERTIFICATE table so that
certificate objects can be stored and retrieved into the CERTIFICATE table. This cla ss
should also implement Comparable interface and compareTo method, which will be used
to sort the elements in case you set sort="natural" in your mapping file (see below
mapping file):

public class Certificate implements Comparable <Certificate>{


private int id;
61
Hibernate

private String name;

public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public int compareTo(Certificate that){
final int BEFORE = -1;
final int AFTER = 1;

if (that == null) {
return BEFORE;
}

Comparable thisCertificate = this.getName();


Comparable thatCertificate = that.getName();

if(thisCertificate == null) {
return AFTER;
} else if(thatCertificate == null) {
return BEFORE;
} else {
return thisCertificate.compareTo(thatCertificate);
}
62
Hibernate

}
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate how to map the defined classes
to the database tables. The <set> element will be used to def ine the rule for SortedSet
collection used.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<set name="certificates" cascade="all" sort="MyClass">
<key column="employee_id"/>
<one-to-many class="Certificate"/>
</set>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>

<class name="Certificate" table="CERTIFICATE">


<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>

63
Hibernate

</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <set> element is used to set the relationship between Certificate and
Employee classes. We used the cascade attribute in the <set> element to tell
Hibernate to persist the Certificate objects at the same time as the Employee
objects. The name attribute is set to the defined SortedSet variable in the parent
class, in our case it is certificates. The sort attribute can be set to natural to have
natural sorting or it can be set to a custom class implement i ng
java.util.Comparator. We have used a class MyClass, which impleme nt s
java.util.Comparator to reverse the sorting order imple mented in Certificate class.

 The <key> element is the column in the CERTIFICATE table that holds the foreign
key to the parent object i.e. table EMPLOYEE.

64
Hibernate

 The <one-to-many> element indicates that one Employee object relates to many
Certificate objects and, as such, the Certificate object must have an Employee
parent associated with it. You can use either <one-to-one>, <many-to-one> or
<many-to-many> elements based on your requirement.

If we use sort="natural" setting, then we do not need to create a separate class because
Certificate class already has implemented Comparable interface and hibernate will use
compareTo() method defined in Certificate class to compare certificate names. But we are
using a custom comparator class MyClass in our mapping file so we would have to create
this class based on our sorting algorithm. Let us do descending sorting in this class using
this class.

import java.util.Comparator;

public class MyClass implements Comparator<Certificate>{


public int compare(Certificate o1, Certificate o2) {
final int BEFORE = -1;
final int AFTER = 1;

/* To reverse the sorting order, multiple by -1 */


if (o2 == null) {
return BEFORE * -1;
}

Comparable thisCertificate = o1.getName();


Comparable thatCertificate = o2.getName();

if(thisCertificate == null) {
return AFTER * 1;
} else if(thatCertificate == null) {
return BEFORE * -1;
} else {
return thisCertificate.compareTo(thatCertificate) * -1;
}
}
}

65
Hibernate

CreateApplication Class
Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee’s records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();
/* Let us have a set of certificates for the first employee */
TreeSet set1 = new TreeSet();
set1.add(new Certificate("MCA"));
set1.add(new Certificate("MBA"));
set1.add(new Certificate("PMP"));

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

/* Another set of certificates for the second employee */


TreeSet set2 = new TreeSet();
set2.add(new Certificate("BCA"));
set2.add(new Certificate("BA"));

66
Hibernate

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down all the employees */


ME.listEmployees();

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, SortedSet cert){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
67
Hibernate

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
SortedSet certificates = employee.getCertificates();
for (Iterator iterator2 =
certificates.iterator(); iterator2.hasNext();){
Certificate certName = (Certificate) iterator2.next();
System.out.println("Certificate: " + certName.getName());
}
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
68
Hibernate

Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.


69
Hibernate

 Create Employee.java source file as shown above and compile it.

 Create Certificate.java source file as shown above and compile it.

 Create MyClass.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute Manage Employee binary to run the program.

You would get notification from hibernate library on the screen, and same time records would
be created in EMPLOYEE and CERTIFICATE tables. You can see certificates have been
sorted in reverse order. You can try by changing your mapping file, simply set
sort="natural" and execute your program and compare the results.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Certificate: PMP
Certificate: MCA
Certificate: MBA
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: PMP
Certificate: MCA
Certificate: MBA

If you check your EMPLOYEE and CERTIFICATE tables, they should have the following
records:

mysql> select * from employee;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 1 | Manoj | Kumar | 5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

mysql> select * from certificate;


+----+------------------+-------------+

70
Hibernate

| id | certificate_name | employee_id |
+----+------------------+-------------+
| 1 | MBA | 1 |
| 2 | PMP | 1 |
| 3 | MCA | 1 |
+----+------------------+-------------+
3 rows in set (0.00 sec)

mysql>

Hibernate – List Mappings


A List is a java collection that stores elements in sequence and allow duplicate elements.
The user of this interface has precise control over where in the list, each element is
inserted. The user can access elements by their integer index, and search for elements in
the list. More formally, lists typically allow pairs of elements e1 and e2 such that
e1.equals(e2), and they typically allow multiple null elements if they allow null element s
at all.

A List is mapped with a <list> element in the mapping table and initialized with
java.util.ArrayList.

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table ,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Further, assume each employee can have one or more certificate associated with him/her.
A List collection mapping needs an index column in the collection table. The index column
defines the position of the element in the collection. So, we will store certificate related
information in a separate table having the following structure:

create table CERTIFICATE (


id INT NOT NULL auto_increment,
certificate_name VARCHAR(30) default NULL,
71
Hibernate

idx INT default NULL,


employee_id INT default NULL,
PRIMARY KEY (id)
);

There will be one-to-many relationship between EMPLOYEE and CERTIFICATE objects.

Define POJO Classes


Let us implement a POJO class Employee, which will be used to persist the objects related
to EMPLOYEE table and having a collection of certificates in List variable.

import java.util.*;

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;
private List certificates;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;

72
Hibernate

}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}

public List getCertificates() {


return certificates;
}
public void setCertificates( List certificates ) {
this.certificates = certificates;
}
}

We need to define another POJO class corresponding to CERTIFICATE table so that


certificate objects can be stored and retrieved into the CERTIFICATE table.

public class Certificate{


private int id;
private String name;

public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {

73
Hibernate

this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate how to map the defined classes
to the database tables. The <list> element will be used to define the rule for List collection
used. The index of list is always of type integer and is mapped using the <list -index>
element.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<list name="certificates" cascade="all">
<key column="employee_id"/>
<list-index column="idx"/>
<one-to-many class="Certificate"/>
</list>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
74
Hibernate

</class>

<class name="Certificate" table="CERTIFICATE">


<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

75
Hibernate

 The <list> element is used to set the relationship between Certificate and
Employee classes. We used the cascade attribute in the <list> element to tell
Hibernate to persist the Certificate objects at the same time as the Employee
objects. The name attribute is set to the defined List variable in the parent class,
in our case, it is certificates.

 The <key> element is the column in the CERTIFICATE table that holds the foreign
key to the parent object i.e. table EMPLOYEE.

 The <list-index> element is used to keep the position of the element and map
with the index column in the collection table. The index of the persistent list starts
at zero. You could change this, for example, with <list -index base="1".../> in your
mapping.

 The <one-to-many> element indicates that one Employee object relates to many
Certificate objects and, as such, the Certificate object must have a n Employee
parent associated with it. You can use either <one-to-one>, <many-to-one> or
<many-to-many> elements based on your requirement. If we changed this
example to use a many-to-many relationship, we would need an association table
to map between the parent and the child objects.

CreateApplication Class
Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee's records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();
76
Hibernate

/* Let us have a set of certificates for the first employee */


ArrayList set1 = new ArrayList();
set1.add(new Certificate("MCA"));
set1.add(new Certificate("MBA"));
set1.add(new Certificate("PMP"));

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

/* Another set of certificates for the second employee */


ArrayList set2 = new ArrayList();
set2.add(new Certificate("BCA"));
set2.add(new Certificate("BA"));

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down all the employees */


ME.listEmployees();

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, ArrayList cert){
Session session = factory.openSession();
Transaction tx = null;
77
Hibernate

Integer employeeID = null;


try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
List certificates = employee.getCertificates();
for (Iterator iterator2 =
certificates.iterator(); iterator2.hasNext();){
Certificate certName = (Certificate) iterator2.next();
System.out.println("Certificate: " + certName.getName());
}
}
78
Hibernate

tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
79
Hibernate

}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


Here are the steps to compile and run the above application using Eclipse IDE. Make sure
that all the required jars are added to the project. .

 Create hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Certificate.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute Manage Employee binary to run the program.

You would get the following result on the screen, and same time records would be created
in EMPLOYEE and CERTIFICATE tables. You can see, certificates have been sorted in
reverse order. You can try by changing your mapping file, simply set sort="natural" and
execute your program and compare the results.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Certificate: MCA
Certificate: MBA
Certificate: PMP
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MCA
Certificate: MBA

80
Hibernate

Certificate: PMP

If you check your EMPLOYEE and CERTIFICATE tables, they should have the following
records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 51 | Manoj | Kumar | 5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

mysql> select * from CERTIFICATE;


+----+------------------+------+-------------+
| id | certificate_name | idx | employee_id |
+----+------------------+------+-------------+
| 6 | MCA | 0 | 51 |
| 7 | MBA | 1 | 51 |
| 8 | PMP | 2 | 51 |
+----+------------------+------+-------------+
3 rows in set (0.00 sec

mysql>

Alternatively, you could map a Java array instead of a list. An array mapping is virtually
identical to the previous example, except with different element and attribute names
(<array> and <array-index>). However, for reasons explained earlier, Hibernat e
applications rarely use arrays.

Hibernate – Bag Mappings


A Bag is a java collection that stores elements without caring about the sequencing , but
allow duplicate elements in the list. A bag is a random grouping of the objects in the list.

A Collection is mapped with a <bag> element in the mapping table and initialize d with
java.util.ArrayList.

81
Hibernate

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table ,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Further, assume each employee can have one or more certificate associated with him/her.
We will store certificate related information in a separate table having the following
structure:

create table CERTIFICATE (


id INT NOT NULL auto_increment,
certificate_name VARCHAR(30) default NULL,
employee_id INT default NULL,
PRIMARY KEY (id)
);

There will be one-to-many relationship between EMPLOYEE and CERTIFICATE objects.

Define POJO Classes


Let us implement a POJO class Employee, which will be used to persist the objects related
to EMPLOYEE table and having a collection of certificates in List variable.

import java.util.*;

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;
private Collection certificates;

public Employee() {}
public Employee(String fname, String lname, int salary) {
82
Hibernate

this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}

public Collection getCertificates() {


return certificates;
}
public void setCertificates( Collection certificates ) {
this.certificates = certificates;
}

83
Hibernate

We need to define another POJO class corresponding to CERTIFICATE table so that


certificate objects can be stored and retrieved into the CERTIFICATE table.

public class Certificate{


private int id;
private String name;

public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate how to map the defined classes
to the database tables. The <bag> element will be used to define the rule for the Collection
used.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>

84
Hibernate

<class name="Employee" table="EMPLOYEE">


<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<bag name="certificates" cascade="all">
<key column="employee_id"/>
<one-to-many class="Certificate"/>
</bag>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>

<class name="Certificate" table="CERTIFICATE">


<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

85
Hibernate

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <bag> element is used to set the relationship between Certificate and
Employee classes. We used the cascade attribute in the <bag> element to tell
Hibernate to persist the Certificate objects at the same time as the Employee
objects. The name attribute is set to the defined Collection variable in the parent
class, in our c ase it is certificates.

 The <key> element is the column in the CERTIFICATE table that holds the foreign
key to the parent object i.e. table EMPLOYEE.

 The <one-to-many> element indicates that one Employee object relates to many
Certificate objects and, as such, the Certificate object must have an Employee
parent associated with it. You can use either <one-to-one>, <many-to-one> or
<many-to-many> elements based on your requirement.

CreateApplication Class
Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employees’ records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {

86
Hibernate

private static SessionFactory factory;


public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();
/* Let us have a set of certificates for the first employee */
ArrayList set1 = new ArrayList();
set1.add(new Certificate("MCA"));
set1.add(new Certificate("MBA"));
set1.add(new Certificate("PMP"));

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

/* Another set of certificates for the second employee */


ArrayList set2 = new ArrayList();
set2.add(new Certificate("BCA"));
set2.add(new Certificate("BA"));

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down all the employees */


87
Hibernate

ME.listEmployees();

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, ArrayList cert){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
88
Hibernate

System.out.print(" Last Name: " + employee.getLastName());


System.out.println(" Salary: " + employee.getSalary());
Collection certificates = employee.getCertificates();
for (Iterator iterator2 =
certificates.iterator(); iterator2.hasNext();){
Certificate certName = (Certificate) iterator2.next();
System.out.println("Certificate: " + certName.getName());
}
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
89
Hibernate

public void deleteEmployee(Integer EmployeeID){


Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Certificate.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get some notifications from hibernate library on the screen, and same time records
would be created in EMPLOYEE and CERTIFICATE tables. You can see , certificates has been
sorted in reverse order. You can try by changing your mapping file, simply set
sort="natural" and execute your program and compare the results.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Certificate: MCA
90
Hibernate

Certificate: MBA
Certificate: PMP
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MCA
Certificate: MBA
Certificate: PMP

If you check your EMPLOYEE and CERTIFICATE tables, they should have the following
records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 53 | Manoj | Kumar | 5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

mysql> select * from CERTIFICATE;


+----+------------------+-------------+
| id | certificate_name | employee_id |
+----+------------------+-------------+
| 11 | MCA | 53 |
| 12 | MBA | 53 |
| 13 | PMP | 53 |
+----+------------------+-------------+
3 rows in set (0.00 sec)

mysql>

Hibernate – Map Mappings


A Map is a java collection that stores elements in key-value pairs and does not allow
duplicate elements in the list. The Map interface provides three collection views, which

91
Hibernate

allow a map's contents to be viewed as a set of keys, collection of values, or set of key-
value mappings.

A Map is mapped with a <map> element in the mapping table and an unordered map can
be initialized with java.util.HashMap.

Define RDBMS Tables


Consider a situation where we need to store our employee records in the EMPLOYEE table,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Further, assume eac h employee can have one or more certificate associated with him/her.
We will store certificate related information in a separate table having the following
structure:

create table CERTIFICATE (


id INT NOT NULL auto_increment,
certificate_type VARCHAR(40) default NULL,
certificate_name VARCHAR(30) default NULL,
employee_id INT default NULL,
PRIMARY KEY (id)
);

There will be one-to-many relationship between EMPLOYEE and CERTIFICATE objects.

Define POJO Classes


Let us implement a POJO class Employee, which will be used to persist the objects related
to EMPLOYEE table and having a collection of certificates in List variable.

import java.util.*;

public class Employee {


private int id;
private String firstName;
private String lastName;
92
Hibernate

private int salary;


private Map certificates;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}

public Map getCertificates() {


return certificates;
93
Hibernate

}
public void setCertificates( Map certificates ) {
this.certificates = certificates;
}
}

We need to define another POJO class corresponding to CERTIFICATE table so that


certificate objects can be stored and retrieved into the CERTIFICATE table.

public class Certificate{


private int id;
private String name;

public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate how to map the defined classes
to the database tables. The <map> element will be used to define the rule for the Map
used.

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


<!DOCTYPE hibernate-mapping PUBLIC

94
Hibernate

"-//Hibernate/Hibernate Mapping DTD//EN"


"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<map name="certificates" cascade="all">
<key column="employee_id"/>
<index column="certificate_type" type="string"/>
<one-to-many class="Certificate"/>
</map>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>

<class name="Certificate" table="CERTIFICATE">


<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

95
Hibernate

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. T he
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <map> element is used to set the relationship between Certificate and
Employee classes. We used the cascade attribute in the <map> element t o tell
Hibernate to persist the Certificate objects at the same time as the Employee
objects. The name attribute is set to the defined Map variable in the parent class,
in our case it is certificates.

 The <index> element is used to represents the key parts of the key/value map
pair. The key will be stored in the column certificate_type using a type of string.

 The <key> element is the column in the CERTIFICATE table that holds the foreign
key to the parent object i.e. table EMPLOYEE.

 The <one-to-many> element indicates that one Employee object relates to many
Certificate objects and, as such, the Certificate object must have a n Employee
parent associated with it. You can use either <one-to-one>, <many-to-one> or
<many-to-many> elements based on your requirement.

CreateApplication Class
Finally, we will create our application class with the main() method to run the application.
We will use this application to save an Employee record along with a list of certificates and
then we will apply CRUD operations on that record.

import java.util.*;

96
Hibernate

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();
/* Let us have a set of certificates for the first employee */
HashMap set = new HashMap();
set.put("ComputerScience", new Certificate("MCA"));
set.put("BusinessManagement", new Certificate("MBA"));
set.put("ProjectManagement", new Certificate("PMP"));

/* Add employee records in the database */


Integer empID = ME.addEmployee("Manoj", "Kumar", 4000, set);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID, 5000);

/* List down all the employees */


ME.listEmployees();

97
Hibernate

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, HashMap cert){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
Map ec = employee.getCertificates();
System.out.println("Certificate: " +
98
Hibernate

(((Certificate)ec.get("ComputerScience")).getName()));
System.out.println("Certificate: " +
(((Certificate)ec.get("BusinessManagement")).getName()));
System.out.println("Certificate: " +
(((Certificate)ec.get("ProjectManagement")).getName()));
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
99
Hibernate

try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using
Eclipse IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in c onfiguration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Certificate.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute Manage Employee binary to run the program.

You would get some notifications from Hibernate library on the screen, and at the same
time, records would be created in EMPLOYEE and CERTIFICATE tables.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Certificate: MCA
Certificate: MBA
Certificate: PMP
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MCA

100
Hibernate

Certificate: MBA
Certificate: PMP

If you check your EMPLOYEE and CERTIFICATE tables, they should have the following
records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 60 | Manoj | Kumar | 5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

mysql>select * from CERTIFICATE;


+----+--------------------+------------------+-------------+
| id | certificate_type | certificate_name | employee_id |
+----+--------------------+------------------+-------------+
| 16 | ProjectManagement | PMP | 60 |
| 17 | BusinessManagement | MBA | 60 |
| 18 | ComputerScience | MCA | 60 |
+----+--------------------+------------------+-------------+
3 rows in set (0.00 sec)
mysql>

Hibernate – SortedMap Mappings


A SortedMap is a similar java collection as Map that stores elements in key-value pairs
and provides a total ordering on its keys. Duplicate elements are not allowed in the map.
The map is ordered according to the natural ordering of its keys, or by a Comparat or
typically provided at sorted map creation time.

A SortedMap is mapped with a <map> element in the mapping table and an ordered map
can be initialized with java.util.TreeMap.

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
101
Hibernate

first_name VARCHAR(20) default NULL,


last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Further, assume each employee can have one or more certificate associated with him/her.
We will store certificate related information in a separate table having the following
structure:

create table CERTIFICATE (


id INT NOT NULL auto_increment,
certificate_type VARCHAR(40) default NULL,
certificate_name VARCHAR(30) default NULL,
employee_id INT default NULL,
PRIMARY KEY (id)
);

There will be one-to-many relationship between EMPLOYEE and CERTIFICATE objects.

Define POJO Classes


Let us implement a POJO class Employee, which will be used to persist the objects related
to EMPLOYEE table and having a collection of certificates in List variable .

import java.util.*;

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;
private SortedMap certificates;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}

102
Hibernate

public int getId() {


return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}

public SortedMap getCertificates() {


return certificates;
}
public void setCertificates( SortedMap certificates ) {
this.certificates = certificates;
}
}

We need to define another POJO class corresponding to CERTIFICATE table so that


certificate objects can be stored and retrieved into the CERTIFICATE table. This class
should also implement Comparable interface and compareTo method, which will be used

103
Hibernate

to sort the key elements of the SortedMap in case you set sort ="natural" in your mapping
file (see below mapping file).

public class Certificate implements Comparable <String>{


private int id;
private String name;

public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public int compareTo(String that){
final int BEFORE = -1;
final int AFTER = 1;

if (that == null) {
return BEFORE;
}

Comparable thisCertificate = this;


Comparable thatCertificate = that;

if(thisCertificate == null) {
return AFTER;
} else if(thatCertificate == null) {
104
Hibernate

return BEFORE;
} else {
return thisCertificate.compareTo(thatCertificate);
}
}
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate how to map the defined classes
to the database tables. The <map> element will be used to define the rule for the Map
used.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mappin g DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<map name="certificates" cascade="all" sort="MyClass">
<key column="employee_id"/>
<index column="certificate_type" type="string"/>
<one-to-many class="Certificate"/>
</map>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>

<class name="Certificate" table="CERTIFICATE">

105
Hibernate

<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are alrea dy familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <map> element is used to set the relationship between Certificate and
Employee classes. We used the cascade attribute in the <map> element to tell
Hibernate to persist the Certificate objects at the same time as the Employee
objects. The name attribute is set to the defined SortedMap variable in the parent
class, in our case it is certificates. The sort attribute can be set to natural to have

106
Hibernate

natural sorting or it can be set to a custom class implement i ng


java.util.Comparator. We have used a class MyClass, which impleme nt s
java.util.Comparator to reverse the sorting order implemented in Certificate class.

 The <index> element is used to represents the key parts of the key/value map
pair. The key will be stored in the column certificate_type using a type of string.

 The <key> element is the column in the CERTIFICATE table that holds the foreign
key to the parent object i.e. table EMPLOYEE.

 The <one-to-many> element indicates that one Employee object relates to many
Certificate objects and, as such, the Certificate object must have a n Employee
parent associated with it. You can use either <one-to-one>, <many-to-one> or
<many-to-many> elements based on your requirement.

If we use sort="natural" setting, then we do not need to create a separate class because
Certificate class already has implemented Comparable interface and hibernate will use
compareTo() method defined in Certificate class to compare SortedMap keys. But we are
using a custom comparator class MyClass in our mapping file so we would have to create
this class based on our sorting algorithm. Let us do descending sorting of the keys available
in the map.

import java.util.Comparator;

public class MyClass implements Comparator <String>{


public int compare(String o1, String o2) {
final int BEFORE = -1;
final int AFTER = 1;

/* To reverse the sorting order, multiple by -1 */


if (o2 == null) {
return BEFORE * -1;
}

Comparable thisCertificate = o1;


Comparable thatCertificate = o2;

if(thisCertificate == null) {
return AFTER * 1;
} else if(thatCertificate == null) {
return BEFORE * -1;
} else {
return thisCertificate.compareTo(thatCertificate) * -1;

107
Hibernate

}
}
}

Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee's records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
ManageEmployee ME = new ManageEmployee();
/* Let us have a set of certificates for the first employee */
TreeMap set1 = new TreeMap();
set1.put("ComputerScience", new Certificate("MCA"));
set1.put("BusinessManagement", new Certificate("MBA"));
set1.put("ProjectManagement", new Certificate("PMP"));

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

/* Another set of certificates for the second employee */


TreeMap set2 = new TreeMap();
108
Hibernate

set2.put("ComputerScience", new Certificate("MCA"));


set2.put("BusinessManagement", new Certificate("MBA"));

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down all the employees */


ME.listEmployees();

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, TreeMap cert){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
109
Hibernate

session.close();
}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
SortedMap<String, Certificate> map =
employee.getCertificates();
for(Map.Entry<String,Certificate> entry : map.entrySet()){
System.out.print("\tCertificate Type: " + entry.getKey());
System.out.println(", Name: " +
(entry.getValue()).getName());
}
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
110
Hibernate

Session session = factory.openSession();


Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

111
Hibernate

Compilation and Execution


Here are the steps to compile and run the above application using Eclipse IDE. Make sure
that all the required jars are added to the project.

 Create hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Certificate.java source file as shown above and compile it.

 Create MyClass.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute Manage Employee binary to run the program.

You would get the following result on the screen, and same time, records would be created
in EMPLOYEE and CERTIFICATE tables. You can see, certificates type has been sorted in
reverse order. You can try by changing your mapping file, simply set sort="natural" and
execute your program and compare the results.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Certificate Type: ProjectManagement, Name: PMP
Certificate Type: ComputerScience, Name: MCA
Certificate Type: BusinessManagement, Name: MBA
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate Type: ComputerScience, Name: MCA
Certificate Type: BusinessManagement, Name: MBA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate Type: ProjectManagement, Name: PMP
Certificate Type: ComputerScience, Name: MCA
Certificate Type: BusinessManagement, Name: MBA

If you check your EMPLOYEE and CERTIFICATE tables, they should have the following
records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 74 | Manoj | Kumar | 500 0 |
112
Hibernate

+----+------------+-----------+--------+
1 row in set (0.00 sec)

mysql> select * from CERTIFICATE;


+----+--------------------+------------------+-------------+
| id | certificate_type | certificate_name | employee_id |
+----+--------------------+------------------+-------------+
| 52 | BusinessManagement | MBA | 74 |
| 53 | ComputerScience | MCA | 74 |
| 54 | ProjectManagement | PMP | 74 |
+----+--------------------+------------------+-------------+
3 rows in set (0.00 sec)

mysql>

Association Mappings
The mapping of associations between entity classes and the relationships between tables
is the soul of ORM. Following are the four ways in which the cardinality of the relationship
between the objects can be expressed. An association mapping can be unidirectional as
well as bidirectional.

Mapping type Description

Many-to-One Mapping many-to-one relationship using Hibernate


One-to-One Mapping one-to-one relationship using Hibernate
One-to-Many Mapping one-to-many relationship using Hibernate
Many-to-Many Mapping many-to-many relationship using Hibernate

Hibernate – Many-to-One Mappings


A many-to-one association is the most common kind of association where an Object can
be associated with multiple objects. For example, the same address object can be
associated with multiple employee objects.

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table ,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,

113
Hibernate

first_name VARCHAR(20) default NULL,


last_name VARCHAR(20) default NULL,
salary INT default NULL,
address INT NOT NULL,
PRIMARY KEY (id)
);

Further, many employee can have same address, so this association can be presented
using many-to-one association. We will store address related information in a separate
table having the following structure:

create table ADDRESS (


id INT NOT NULL auto_increment,
street_name VARCHAR(40) default NULL,
city_name VARCHAR(40) default NULL,
state_name VARCHAR(40) default NULL,
zipcode VARCHAR(10) default NULL,
PRIMARY KEY (id)
);

Create both the RBDMS tables and keep them ready for the next implementation.

Define POJO Classes


Let us implement a POJO class Employee, which will be used to persist the objects related
to EMPLOYEE table and having a variable of Address type.

import java.util.*;

public class Employee{


private int id;
private String firstName;
private String lastName;
private int salary;
private Address address;

public Employee() {}
public Employee(String fname, String lname,
int salary, Address address ) {
this.firstName = fname;

114
Hibernate

this.lastName = lname;
this.salary = salary;
this.address = address;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}

public Address getAddress() {


return address;
}
public void setAddress( Address address ) {
this.address = address;
}

115
Hibernate

We need to define another POJO class corresponding to ADDRESS table so that address
objects can be stored and retrieved into the ADDRESS table.

import java.util.*;

public class Address{


private int id;
private String street;
private String city;
private String state;
private String zipcode;

public Address() {}
public Address(String street, String city,
String state, String zipcode) {
this.street = street;
this.city = city;
this.state = state;
this.zipcode = zipcode;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet( String street ) {
this.street = street;
}
public String getCity() {
116
Hibernate

return city;
}
public void setCity( String city ) {
this.city = city;
}
public String getState() {
return state;
}
public void setState( String state ) {
this.state = state;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode( String zipcode ) {
this.zipcode = zipcode;
}

Define Hibernate Mapping File


Let us develop our mapping files, which instructs Hibernate how to map the defined classes
to the database tables. The <many-to-one> element will be used to define the rule to
establish a many-to-one relationship between EMPLOYEE and ADDRESS entities.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">

117
Hibernate

<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
<many-to-one name="address" column="address"
class="Address" not-null="true"/>
</class>

<class name="Address" table="ADDRESS">


<meta attribute="class-description">
This class contains the address detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="street" column="street_name" type="string"/>
<property name="city" column="city_name" type="string"/>
<property name="state" column="state_name" type="string"/>
<property name="zipcode" column="zipcode" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
118
Hibernate

type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers t o the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <many-to-one> element is used to set the relationship between EMPLOYEE


and ADDRESS entities. The name attribute is set to the defined variable in the
parent class, in our case it is address. The column attribute is used to set the
column name in the parent table EMPLOYEE.

Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee's records along with their addresses and
then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
ManageEmployee ME = new ManageEmployee();

/* Let us have one address object */


119
Hibernate

Address address = ME.addAddress("Kondapur","Hyderabad","AP","532");

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, address);

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, address);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down all the employees */


ME.listEmployees();

/* Method to add an address record in the database */


public Address addAddress(String street, String city,
String state, String zipcode) {
Session session = factory.openSession();
Transaction tx = null;
Integer addressID = null;
Address address = null;
try{
tx = session.beginTransaction();
address = new Address(street, city, state, zipcode);
addressID = (Integer) session.save(address);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
120
Hibernate

e.printStackTrace();
}finally {
session.close();
}
return address;
}

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, Address address){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary, address);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
121
Hibernate

Employee employee = (Employee) iterator.next();


System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
Address add = employee.getAddress();
System.out.println("Address ");
System.out.println("\tStreet: " + add.getStreet());
System.out.println("\tCity: " + add.getCity());
System.out.println("\tState: " + add.getState());
System.out.println("\tZipcode: " + add.getZipcode());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
122
Hibernate

}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Address.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get some notifications from hibernate library on the screen, and at the same time,
records would be created in EMPLOYEE and ADDRESS tables.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000

123
Hibernate

Address
Street: Kondapur
City: Hyderabad
State: AP
Zipcode: 532
First Name: Dilip Last Name: Kumar Salary: 3000
Address
Street: Kondapur
City: Hyderabad
State: AP
Zipcode: 532
First Name: Manoj Last Name: Kumar Salary: 5000
Address
Street: Kondapur
City: Hyderabad
State: AP
Zipcode: 532

If you check your EMPLOYEE and ADDRESS tables, they should have the following records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+---------+
| id | first_name | last_name | salary | address |
+----+------------+-----------+--------+---------+
| 1 | Manoj | Kumar | 5000 | 5 |
+----+------------+-----------+--------+---------+
1 row in set (0.00 sec)

mysql> select * from ADDRESS;


+----+-------------+-----------+------------+---------+
| id | street_name | city_name | state_name | zipcode |
+----+-------------+-----------+------------+---------+
| 1 | Kondapur | Hyderabad | AP | 532 |
+----+-------------+-----------+------------+---------+
1 row in set (0.00 sec)

124
Hibernate

mysql>

Hibernate – One-to-One Mappings


A one-to-one association is similar to many-to-one association with a difference that
the column will be set as unique. For example, an address object can be associated with
a single employee object.

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table ,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
address INT NOT NULL,
PRIMARY KEY (id)
);

Further, assuming that an address can be associated a single employee only, so this
association can be presented using one-to-one association. We will store address related
information in a separate table having the following structure:

create table ADDRESS (


id INT NOT NULL auto_increment,
street_name VARCHAR(40) default NULL,
city_name VARCHAR(40) default NULL,
state_name VARCHAR(40) default NULL,
zipcode VARCHAR(10) default NULL,
PRIMARY KEY (id)
);

Create both the RBDMS tables and keep them ready for the next implementation.

Define POJO Classes


Let us implement a POJO class Employee, which will be used to persist the objects related
to EMPLOYEE table and having a variable of Address type.

import java.util.*;

125
Hibernate

public class Employee{


private int id;
private String firstName;
private String lastName;
private int salary;
private Address address;

public Employee() {}
public Employee(String fname, String lname,
int salary, Address address ) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
this.address = address;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
126
Hibernate

}
public void setSalary( int salary ) {
this.salary = salary;
}

public Address getAddress() {


return address;
}
public void setAddress( Address address ) {
this.address = address;
}
}

We need to define another POJO class corresponding to ADDRESS table so that address
objects can be stored and retrieved into the ADDRESS table.

import java.util.*;

public class Address{


private int id;
private String street;
private String city;
private String state;
private String zipcode;

public Address() {}
public Address(String street, String city,
String state, String zipcode) {
this.street = street;
this.city = city;
this.state = state;
this.zipcode = zipcode;
}
public int getId() {
return id;
}
public void setId( int id ) {

127
Hibernate

this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet( String street ) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity( String city ) {
this.city = city;
}
public String getState() {
return state;
}
public void setState( String state ) {
this.state = state;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode( String zipcode ) {
this.zipcode = zipcode;
}

Define Hibernate Mapping File


Let us develop our mapping files which instructs Hibernate how to map the defined classes
to the database tables. The <many-to-one> element will be used to define the rule to
establish a one-to-one relationship between EMPLOYEE and ADDRESS entities, but column
attribute will be set to unique constraint and rest of the mapping file will remain as it was
in case of many-to-one association.

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

128
Hibernate

<!DOCTYPE hibernate-mapping PUBLIC


"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
<many-to-one name="address" column="address" unique="true"
class="Address" not-null="true"/>
</class>

<class name="Address" table="ADDRESS">


<meta attribute="class-description">
This class contains the address detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="street" column="street_name" type="string"/>
<property name="city" column="city_name" type="string"/>
<property name="state" column="state_name" type="string"/>
<property name="zipcode" column="zipcode" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:
129
Hibernate

 The mapping document is an XML document having <hibernate-mapping> as


the root element which contains two <class> elements corresponding to each class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <many-to-one> element is used to set the relationship between EMPLOYEE


and ADDRESS entities. The name attribute is set to the defined variable in the
parent class, in our case it is address. The column attribute is used to set the
column name in the parent table EMPLOYEE, which is set to unique so that only
one Employee object can be associated with an address object.

Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee's records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {

130
Hibernate

try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();

/* Let us have one address object */


Address address1 = ME.addAddress("Kondapur","Hyderabad","AP","532");

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, address1);

/* Let us have another address object */


Address address2 = ME.addAddress("Saharanpur","Ambehta","UP","111");

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, address2);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* List down all the employees */


ME.listEmployees();

/* Method to add an address record in the database */


public Address addAddress(String street, String city,
String state, String zipcode) {
Session session = factory.openSession();
Transaction tx = null;
131
Hibernate

Integer addressID = null;


Address address = null;
try{
tx = session.beginTransaction();
address = new Address(street, city, state, zipcode);
addressID = (Integer) session.save(address);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return address;
}

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, Address address){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary, address);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

132
Hibernate

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
Address add = employee.getAddress();
System.out.println("Address ");
System.out.println("\tStreet: " + add.getStreet());
System.out.println("\tCity: " + add.getCity());
System.out.println("\tState: " + add.getState());
System.out.println("\tZipcode: " + add.getZipcode());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
133
Hibernate

employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Address.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get some notificaions from Hibernate library on the screen, and at the same time,
records would be created in EMPLOYEE and ADDRESS tables.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Address
Street: Kondapur
City: Hyderabad
State: AP
Zipcode: 532
First Name: Dilip Last Name: Kumar Salary: 3000
Address
Street: Saharanpur

134
Hibernate

City: Ambehta
State: UP
Zipcode: 111
First Name: Manoj Last Name: Kumar Salary: 5000
Address
Street: Kondapur
City: Hyderabad
State: AP
Zipcode: 532
First Name: Dilip Last Name: Kumar Salary: 3000
Address
Street: Saharanpur
City: Ambehta
State: UP
Zipcode: 111

If you check your EMPLOYEE and CERTIFICATE tables, they should have the following
records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+---------+
| id | first_name | last_name | salary | address |
+----+------------+-----------+--------+---------+
| 7 | Manoj | Kumar | 5000 | 5 |
| 8 | Dilip | Kumar | 3000 | 6 |
+----+------------+-----------+--------+---------+
2 rows in set (0.00 sec)

mysql> select * from ADDRESS;


+----+-------------+-----------+------------+---------+
| id | street_name | city_name | state_name | zipcode |
+----+-------------+-----------+------------+---------+
| 5 | Kondapur | Hyderabad | AP | 532 |
| 6 | Saharanpur | Ambehta | UP | 111 |
+----+-------------+-----------+------------+---------+
2 rows in set (0.00 sec)

135
Hibernate

mysql>

Hibernate – One-to-Many Mappings


A One-to-Many mapping can be implemented using a Set java collection that does not
contain any duplicate element. We already have seen how to map Set collection in
hibernate, so if you already learned Set mapping then you are all set to go with one-to-
many mapping.

A Set is mapped with a <set> element in the mapping table and initialized with
java.util.HashSet. You can use Set collection in your class when there is no duplicate
element required in the collection.

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Further, assume each employee can have one or more certificate associated with him/her.
So, we will store certificate related information in a separate table having the following
structure:

create table CERTIFICATE (


id INT NOT NULL auto_increment,
certificate_name VARCHAR(30) default NULL,
employee_id INT default NULL,
PRIMARY KEY (id)
);

There will be one-to-many relationship between EMPLOYEE and CERTIFICATE objects:

Define POJO Classes


Let us implement our POJO class Employee, which will be used to persist the objects
related to EMPLOYEE table and having a collection of certificates in a Set variable.

import java.util.*;
136
Hibernate

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;
private Set certificates;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
137
Hibernate

this.salary = salary;
}

public Set getCertificates() {


return certificates;
}
public void setCertificates( Set certificates ) {
this.certificates = certificates;
}
}

Now, let us define another POJO class corresponding to CERTIFICATE table so that
certificate objects can be stored and retrieved into the CERTIFICATE table. This class
should also implement both the equals() and hashCode() methods so that Java can
determine whether any two elements/objects are identical.

public class Certificate {


private int id;
private String name;

public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public boolean equals(Object obj) {
if (obj == null) return false;
138
Hibernate

if (!this.getClass().equals(obj.getClass())) return false;

Certificate obj2 = (Certificate)obj;


if((this.id == obj2.getId()) && (this.name.equals(obj2.getName())))
{
return true;
}
return false;
}
public int hashCode() {
int tmp = 0;
tmp = ( id + name ).hashCode();
return tmp;
}
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate how to map the defined classes
to the database tables.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<set name="certificates" cascade="all">
<key column="employee_id"/>
<one-to-many class="Certificate"/>

139
Hibernate

</set>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>

<class name="Certificate" table="CERTIFICATE">


<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to t he property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

140
Hibernate

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <set> element sets the relationship between Certificate and Employee
classes. We used the cascade attribute in the <set> element to tell Hibernate to
persist the Certificate objects at the same time as the Employee objects. The name
attribute is set to the defined Set variable in the parent class, in our case it is
certificates. For each set variable, we need to define a separate set element in the
mapping file.

 The <key> element is the column in the CERTIFICATE table that holds the foreign
key to the parent object i.e. table EMPLOYEE.

 The <one-to-many> element indicates that one Employee object relates to many
Certificate objects.

CreateApplication Class
Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee's records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();
/* Let us have a set of certificates for the first employee */

141
Hibernate

HashSet set1 = new HashSet();


set1.add(new Certificate("MCA"));
set1.add(new Certificate("MBA"));
set1.add(new Certificate("PMP"));

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);

/* Another set of certificates for the second employee */


HashSet set2 = new HashSet();
set2.add(new Certificate("BCA"));
set2.add(new Certificate("BA"));

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down all the employees */


ME.listEmployees();

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, Set cert){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
142
Hibernate

try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
Set certificates = employee.getCertificates();
for (Iterator iterator2 =
certificates.iterator(); iterator2.hasNext();){
Certificate certName = (Certificate) iterator2.next();
System.out.println("Certificate: " + certName.getName());
}
}
tx.commit();
143
Hibernate

}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
144
Hibernate

if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Certificate.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get some notifications from Hibernate Library on the screen, and at the same time,
records would be created in EMPLOYEE and CERTIFICATE tables.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Certificate: MBA
Certificate: PMP
Certificate: MCA
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: BCA
Certificate: BA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MBA
Certificate: PMP
Certificate: MCA

If you check your EMPLOYEE and CERTIFICATE tables, they should have the following
records:
145
Hibernate

mysql> select * from employee;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 1 | Manoj | Kumar | 5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)

mysql> select * from certificate;


+----+------------------+-------------+
| id | certificate_name | employee_id |
+----+------------------+-------------+
| 1 | MBA | 1 |
| 2 | PMP | 1 |
| 3 | MCA | 1 |
+----+------------------+-------------+
3 rows in set (0.00 sec)

mysql>

Hibernate – Many-to-Many Mappings


A Many-to-Many mapping can be implemented using a Set java collection that does not
contain any duplicate element. We already have seen how to map Set collection in
hibernate, so if you already learned Set mapping, then you are all set to go with many-
to-many mapping.

A Set is mapped with a <set> element in the mapping table and initialized with
java.util.HashSet. You can use Set collection in your c lass when there is no duplicate
element required in the collection.

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table ,
which will have the following structure:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,

146
Hibernate

salary INT default NULL,


PRIMARY KEY (id)
);

Further, assume each employee can have one or more certificate associated with him/her
and a similar certificate can be associated with more than one employee. We will store
certificate related information in a separate table, which has the following structure:

create table CERTIFICATE (


id INT NOT NULL auto_increment,
certificate_name VARCHAR(30) default NULL,
PRIMARY KEY (id)
);

Now to implement many-to-many relationship between EMPLOYEE and CERTIFICAT E


objects, we would have to introduce one more intermediate table having Employee ID and
Certificate ID as follows:

create table EMP_CERT (


employee_id INT NOT NULL,
certificate_id INT NOT NULL,
PRIMARY KEY (employee_id,certificate_id)
);

Define POJO Classes


Let us implement our POJO class Employee, which will be used to persist the objects
related to EMPLOYEE table and having a collection of certificates in Set variable.

import java.util.*;

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;
private Set certificates;

public Employee() {}
public Employee(String fname, String lname, int salary) {
147
Hibernate

this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}

public Set getCertificates() {


return certificates;
}
public void setCertificates( Set certificates ) {
this.certificates = certificates;
}

148
Hibernate

Now let us define another POJO class corresponding to CERTIFICATE table so that
certificate objects can be stored and retrieved into the CERTIFICATE table. This class
should also implement both the equals() and hashCode() methods so that Java can
determine whether any two elements/objects are identical.

public class Certificate {


private int id;
private String name;

public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!this.getClass().equals(obj.getClass())) return false;

Certificate obj2 = (Certificate)obj;


if((this.id == obj2.getId()) && (this.name.equals(obj2.getName())))
{
return true;
}
return false;
}
149
Hibernate

public int hashCode() {


int tmp = 0;
tmp = ( id + name ).hashCode();
return tmp;
}
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate — how to map the defined
classes to the database tables. The <set> element will be used to define the rule for many -
to-many relationship.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<set name="certificates" cascade="save-update" table="EMP_CERT">
<key column="employee_id"/>
<many-to-many column="certificate_id" class="Certificate"/>
</set>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>

<class name="Certificate" table="CERTIFICATE">


<meta attribute="class-description">

150
Hibernate

This class contains the certificate records.


</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <set> element sets the relationship between Certificate and Employee
classes. We set cascade attribute to save-update to tell Hibernate to persist the
Certificate objects for SAVE i.e. CREATE and UPDATE operations at the same time
as the Employee objects. The name attribute is set to the defined Set variable in
the parent class, in our case it is certificates. For each set variable, we need to
define a separate set element in the mapping file. Here we used name attribute to
set the intermediate table name to EMP_CERT.
151
Hibernate

 The <key> element is the column in the EMP_CERT table that holds the foreign
key to the parent object i.e. table EMPLOYEE and links to the certification_id in the
CERTIFICATE table.

 The <many-to-many> element indicates that one Employee object relat es to


many Certificate objects and column attributes are used to link intermediat e
EMP_CERT.

CreateApplication Class
Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee's records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();
/* Let us have a set of certificates for the first employee */
HashSet certificates = new HashSet();

certificates.add(new Certificate("MCA"));
certificates.add(new Certificate("MBA"));
certificates.add(new Certificate("PMP"));

/* Add employee records in the database */

152
Hibernate

Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, certificates);

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, certificates);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down all the employees */


ME.listEmployees();

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, Set cert){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
153
Hibernate

}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
Set certificates = employee.getCertificates();
for (Iterator iterator2 =
certificates.iterator(); iterator2.hasNext();){
Certificate certName = (Certificate) iterator2.next();
System.out.println("Certificate: " + certName.getName());
}
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
154
Hibernate

try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

155
Hibernate

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to t he project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create Certificate.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get the following result on the screen, and same time records would be created
in EMPLOYEE, EMP_CERT and CERTIFICATE tables.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Certificate: MBA
Certificate: PMP
Certificate: MCA
First Name: Dilip Last Name: Kumar Salary: 3000
Certificate: MBA
Certificate: PMP
Certificate: MCA
First Name: Manoj Last Name: Kumar Salary: 5000
Certificate: MBA
Certificate: PMP
Certificate: MCA

If you check your EMPLOYEE, EMP_CERT and CERTIFICATE tables, they should have the
following records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 22 | Manoj | Kumar | 5000 |
+----+------------+-----------+--------+
1 row in set (0.00 sec)
156
Hibernate

mysql> select * from CERTIFICATE;


+----+------------------+
| id | certificate_name |
+----+------------------+
| 4 | MBA |
| 5 | PMP |
| 6 | MCA |
+----+------------------+
3 rows in set (0.00 sec)

mysql> select * from EMP_CERT;


+-------------+----------------+
| employee_id | certificate_id |
+-------------+----------------+
| 22 | 4 |
| 22 | 5 |
| 22 | 6 |
+-------------+----------------+
3 rows in set (0.00 sec)
mysql>

Inheritance Mappings
Inheritance Mapping allows you to map the classes to database tables in a hierarchy. There
are three types of inheritance mappings, as listed in the following table.

Mapping type Description

Table Per Class Hierarchy Single table is required to map the whole class hierarchy.

Tables are created with foreign key relation. therefore


Table Per SubClass
duplicates are not allowed.

Tables are created based on the derived classes and does


Table Per Concrete Class
not create table for base class.

157
Hibernate

Hibernate – Table Per Class Hierarchy


Table per class hierarchy means the whole class hierarchy data (the base class and derived
classes data) is stored in one table. The data of the sub-classes are differentiated by the
external cloumn which is declard in the mapping file using discriminator-value attribute.

The class Hierarchy


Take a look at the following illustration. We have two classes Permanent_Employee and
Contract_Employee which are derived from the Employee class. Here we will explain
how to store all the three classes data into one table named Employee without any
repetation of records. The solution is to maintain one column.

Define POJO Classes


Let us create a POJO class named Employee which contains three fields viz. id, name,
and designation. This is the base class of the given class hierarchy.

public class Employee {

private int id;


private String name;
private String designation;
public Employee() {
}
public Employee(int id, String name, String designation) {
this.id = id;
this.name = name;

158
Hibernate

this.designation = designation;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
@Override
public String toString() {
return "Employee [" + id + ", " + name + ", "+ designation + "]";
}

Let us create another POJO class named Permanent_Employee which is derived from
the class Employee.

public class Permanent_Employee extends Employee {


private float Salary;

public Permanent_Employee() {
super();
}

159
Hibernate

public Permanent_Employee(float salary) {


super();
Salary = salary;
}

public float getSalary() {


return Salary;
}

public void setSalary(float salary) {


Salary = salary;
}

@Override
public String toString() {
return "Permanent_Employee [" + Salary + "]";
}

Let us create another POJO class named Contract_Employee which is derived from the
class Employee.

public class Contract_Employee extends Employee {


private float pay_per_hour;

public Contract_Employee() {
super();
}

public Contract_Employee(float pay_per_hour) {


super();
this.pay_per_hour = pay_per_hour;
}

public float getpay_per_hour() {


return pay_per_hour;

160
Hibernate

public void setpay_per_hour(float pay_per_hour) {


this.pay_per_hour = pay_per_hour;
}

@Override
public String toString() {
return "Contract_Employee [pay_per_hour=" + pay_per_hour + "]";
}

Define Hibernate Mapping File


Let us create a mapping file to instruct Hibernate how to map the defined classes to the
database tables. The <subclass> is used to define the deriverd classes
(Permanent_Employee and Contract_Employee) and its fields in the mapping file. The
discriminator-value attribute defines three different values which are used to differentiate
the records of permanent employees and contract employees.

<?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="Employee" table="Employee" discriminator-value="E">
<id name="id">
<generator class="increment"/>
</id>
<discriminator column="Etype" type="string" length="3"/>
<property name="name" length="10"/>
<property name="designation" length="10"/>
<subclass name="permanent_Employee" discriminator-value="PE">
<property name="Salary" length="10"/>
</subclass>
<subclass name="Contract_Employee" discriminator-value="CE">

161
Hibernate

<property name="pay_per_hour" length="20"/>


</subclass>
</class>
</hibernate-mapping>

Finally, we will create our application class with the main() method to run the application.
We will use this application to insert Employee's records along with their details and then
we will apply CRUD operations on those records.

The client program SaveClient is as follows:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class SaveEmployee {

public static void main(String[] args) throws Exception{


Configuration c= new Configuration();
c.configure("/hibernate.cfg.xml");

SessionFactory sf = c.buildSessionFactory();

Session s=sf.openSession();

// transient state
Permanent_Employee e1=new Permanent_Employee(0,"Raju","HR",50000);
Permanent_Employee e2=new
Permanent_Employee(1,"Surendhar","Admin",30000);

Contract_Employee e3= new Contract_Employee(3, "Javed",


"Developer",500);
Contract_Employee e4= new Contract_Employee(4, "Arshad",
"Developer",400);

Transaction t=s.beginTransaction();

try {

162
Hibernate

// attached state
s.save(e1);
s.save(e2);
s.save(e3);
s.save(e4);

// persistent and attached


s.flush();
t.commit();
System.out.println("Records inserted");
}
catch(Exception e) {
e.printStackTrace();
t.rollback();
}
}
}

Compilation and Execution


Here are the steps to compile and run the above mentioned application using Eclipse IDE.
Make sure that all the required jars are added to the project.

 Create hibernate.cfg.xml configuration file as explained in configuration chapter.


 Create Employee.hbm.xml mapping file as shown above.
 Create Employee.java source file as shown above and compile it.
 SaveClient.java source file as shown above and compile it.
 Execute SaceClient class to run the program.

You would get some notifications from Hibernate Library on the screen.

If you check the Employee records on mysql command as follows. Here the column Etype
is the extra column that differentiate the records of Permanent Employee (PE) and
Contract Employee (CE).

mysql> select * form employee;

+----+-------+-----------+-------------+--------+--------------+
| id | Etype | name | designation | Salary | pay_per_hour |
+----+-------+-----------+-------------+--------+--------------+

163
Hibernate

| 1 | PE | Raju | HR | 50000 | NULL |


| 2 | PE | Surendhar | Admin | 30000 | NULL |
| 3 | CE | Javed | Developer | NULL | 500 |
| 4 | CE | Arshad | Developer | NULL | 400 |
+----+-------+-----------+-------------+--------+--------------+
4 rows in set (0.00 sec)

mysql>

Hibernate Table Per Sub-class


In table per sub-class hierarchy, we create as many tables as there are classes in the
hierarchy, and the tables are interliked using Primary key – Foreign key relation.

The class Hierarchy


Take a look at the following hierarchy. Here we have two classes Permanent_Employ e e
and Contract_Employee which are derived from the Employee class. Now the situation
is that we want to store all the three classes data into three tables named as per class
names without any repetition of records. The solution is to maintain the Peimary key -
Foreign key relation between the tables.

Define POJO Classes


Let us create a POJO class named Employee which contains three fields named id, name,
and designation. This is the base class of the given class hierarchy.

164
Hibernate

public class Employee {

private int id;


private String name;
private String designation;
public Employee() {
}
public Employee(int id, String name, String designation) {
this.id = id;
this.name = name;
this.designation = designation;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
@Override
public String toString() {
return "Employee [" + id + ", " + name + ", "+ designation + "]";
}

165
Hibernate

Let us create another POJO class named Permanent_Employee which is derived from
the class Employee.

public class Permanent_Employee extends Employee {


private float Salary;

public Permanent_Employee() {
super();
}

public Permanent_Employee(float salary) {


super();
Salary = salary;
}

public float getSalary() {


return Salary;
}

public void setSalary(float salary) {


Salary = salary;
}

@Override
public String toString() {
return "Permanent_Employee [" + Salary + "]";
}

Let us create another POJO class named Contract_Employee which is derived from the
class Employee.

public class Contract_Employee extends Employee {


private float pay_per_hour;

166
Hibernate

public Contract_Employee() {
super();
}

public Contract_Employee(float pay_per_hour) {


super();
this.pay_per_hour = pay_per_hour;
}

public float getpay_per_hour() {


return pay_per_hour;
}

public void setpay_per_hour(float pay_per_hour) {


this.pay_per_hour = pay_per_hour;
}

@Override
public String toString() {
return "Contract_Employee [pay_per_hour=" + pay_per_hour + "]";
}

Define Hibernate Mapping File


Let us create a mapping file to instruct Hibernate how to map the defined classes to the
database tables. The <joined-subclass> is used define the deriverd classes
(Permanent_Employee and Contract_Employee) and its fields in the mapping file.
The <key> tag is used to define the foreign key relation with the superclass id field.

<?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="Employee" table="Employee">
167
Hibernate

<id name="id">
<generator class="increment"/>
</id>
<property name="name" length="10"/>
<property name="designation" length="10"/>
<joined-subclass name="Permanent_Employee">
<key column="eid"/>
<property name="Salary" length="10"/>
</joined-subclass>
<joined-subclass name="Contract_Employee">
<key column="eid"/>
<property name="pay_per_hour" length="20"/>
</joined-subclass>
</class>
</hibernate-mapping>

Finally, we will create our application class with the main() method to run the application.
We will use this application to insert Employee's records along with their details and then
we will apply CRUD operations on those records.

The client program named SaveClient is as follows:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class SaveEmployee {

public static void main(String[] args) throws Exception{


Configuration c= new Configuration();
c.configure("/hibernate.cfg.xml");

SessionFactory sf = c.buildSessionFactory();

Session s=sf.openSession();

// transient state

168
Hibernate

Permanent_Employee e1=new Permanent_Employee(0,"Raju","HR",50000);


Permanent_Employee e2=new
Permanent_Employee(1,"Surendhar","Admin",30000);

Contract_Employee e3= new Contract_Employee(3, "Javed",


"Developer",500);
Contract_Employee e4= new Contract_Employee(4, "Arshad",
"Developer",400);

Transaction t=s.beginTransaction();

try {
// attached state
s.save(e1);
s.save(e2);
s.save(e3);
s.save(e4);

// persistent and attached


s.flush();
t.commit();
System.out.println("Records inserted");
}
catch(Exception e) {
e.printStackTrace();
t.rollback();
}

Compilation and Execution


Here are the steps to compile and run the above-mentioned application using Eclipse IDE.
Make sure that all the required jars are added to the project.

 Create hibernate.cfg.xml configuration file.

169
Hibernate

 Create Employee.hbm.xml mapping file.


 Create Employee.java source file and compile it.
 SaveClient.java source file and compile it.
 Execute SaceClient class to run the program.

You would get some notifications from the Hibernate Library on the screen. Now check the
Employee records. You can observe the records in these three tables share a relation
among them.

mysql> select * from employee;


+----+-----------+-------------+
| id | name | designation |
+----+-----------+-------------+
| 1 | Raju | HR |
| 2 | Surendhar | Admin |
| 3 | Javed | Developer |
| 4 | Arshad | Developer |
+----+-----------+-------------+
4 rows in set (0.00 sec)

mysql>mysql> select * from Permanent_Employee;


+-----+--------+
| eid | Salary |
+-----+--------+
| 1 | 50000 |
| 2 | 30000 |
+-----+--------+
2 rows in set (0.00 sec)

mysql> select * from Contract_Employee;


+-----+--------------+
| eid | pay_per_hour |
+-----+--------------+
| 3 | 500 |
| 4 | 400 |
+-----+--------------+
2 rows in set (0.00 sec)

170
Hibernate

Hibernate Table Per Concrete Class


In table per concrete class hierarchy, we create as many tables as there are sub-classes
in the hierarchy. However all the tables share the Employee class records. That means, in
each sub-class table stores the superclass field values as columns.

The class Hierarchy


In the following illustration, we have two classes Permanent_Employee and
Contract_Employee which are derived from the Employee class. Now the situation is
that we want to store all the three classes data into sub-class tables named
(Parmanent_Employee and Contract_Employee). The solution is to share the Employee
class fields in their sub-classes (Parmanent_Employee and Contract_Employee).

Define POJO Classes


Let us create a POJO class named Employee which contains three fields named id, name,
and designation. This is the base class of the given class hierarchy.

public class Employee {

private int id;


private String name;
private String designation;
public Employee() {
}
public Employee(int id, String name, String designation) {
this.id = id;
this.name = name;
171
Hibernate

this.designation = designation;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
@Override
public String toString() {
return "Employee [" + id + ", " + name + ", "+ designation + "]";
}

Let us create another POJO class named Permanent_Employee which is derived from
the class Employee.

public class Permanent_Employee extends Employee {


private float Salary;

public Permanent_Employee() {
super();
}

172
Hibernate

public Permanent_Employee(float salary) {


super();
Salary = salary;
}

public float getSalary() {


return Salary;
}

public void setSalary(float salary) {


Salary = salary;
}

@Override
public String toString() {
return "Permanent_Employee [" + Salary + "]";
}

Let us create another POJO class named Contract_Employee which is derived from the
class Employee.

public class Contract_Employee extends Employee {


private float pay_per_hour;

public Contract_Employee() {
super();
}

public Contract_Employee(float pay_per_hour) {


super();
this.pay_per_hour = pay_per_hour;
}

public float getpay_per_hour() {


return pay_per_hour;

173
Hibernate

public void setpay_per_hour(float pay_per_hour) {


this.pay_per_hour = pay_per_hour;
}

@Override
public String toString() {
return "Contract_Employee [pay_per_hour=" + pay_per_hour + "]";
}

Define Hibernate Mapping File


Let us create a mapping file to instruct Hibernate how to map the defined classes to the
database tables. Each subclass has its own class structure with the superclass fields such
as Id, Name, and Designation.

<?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="Permanent_Employee">
<id name="id">
<generator class="increment"/>
</id>
<property name="name" length="10"/>
<property name="designation" length="10"/>
<property name="Salary" length="10"/>
</class>

<class name="Contract_Employee">
<id name="id">
<generator class="increment"/>

174
Hibernate

</id>
<property name="name" length="10"/>
<property name="designation" length="10"/>
<property name="pay_per_hour" length="20"/>
</class>
</hibernate-mapping>

Finally, we will create our application class with the main() method to run the application.
We will use this application to insert Employee's records along with their details and then
we will apply CRUD operations on those records.

The client program named SaveClient is as follows:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class SaveEmployee {

public static void main(String[] args) throws Exception{


Configuration c= new Configuration();
c.configure("/hibernate.cfg.xml");

SessionFactory sf = c.buildSessionFactory();

Session s=sf.openSession();

// transient state
Permanent_Employee e1=new Permanent_Employee(0,"Raju","HR",50000);
Permanent_Employee e2=new
Permanent_Employee(1,"Surendhar","Admin",30000);

Contract_Employee e3= new Contract_Employee(3, "Javed",


"Developer",500);
Contract_Employee e4= new Contract_Employee(4, "Arshad",
"Developer",400);

Transaction t=s.beginTransaction();

175
Hibernate

try {
// attached state
s.save(e1);
s.save(e2);
s.save(e3);
s.save(e4);

// persistent and attached


s.flush();
t.commit();
System.out.println("Records inserted");
}
catch(Exception e) {
e.printStackTrace();
t.rollback();
}

Compilation and Execution


Here are the steps to compile and run the above-mentioned application using Eclipse IDE.
Make sure that all the required jars are added to the project.

 Create hibernate.cfg.xml configuration file.


 Create Employee.hbm.xml mapping file.
 Create Employee.java source file and compile it.
 SaveClient.java source file and compile it.
 Execute SaceClient class to run the program.

You would get some notifications from Hibernate Library on the screen.

Now, check the records of both the tables. These two tables are independent of each other.

mysql> select * from Permanent_Employee;


+----+-----------+-------------+--------+
| id | name | designation | Salary |
176
Hibernate

+----+-----------+-------------+--------+
| 1 | Raju | HR | 50000 |
| 2 | Surendhar | Admin | 30000 |
+----+-----------+-------------+--------+
2 rows in set (0.00 sec)

mysql> select * from Contract_Employee;


+----+--------+-------------+--------------+
| id | name | designation | pay_per_hour |
+----+--------+-------------+--------------+
| 1 | Javed | Developer | 500 |
| 2 | Arshad | Developer | 400 |
+----+--------+-------------+--------------+
2 rows in set (0.00 sec)

Component Mappings
It is very much possible that an Entity class can have a reference to another class as a
member variable. If the referred class does not have its own life cycle and completely
depends on the life cycle of the owning entity class, then the referred class he nce therefore
is called as the Component class.

The mapping of Collection of Components is also possible in a similar way just as the
mapping of regular Collections with minor configuration differences. We will see these two
mappings in detail with examples.

Mapping type Description


Component Mapping for a class having a reference to another class as a
Mappings member variable.

Hibernate – Component Mappings


A Component mapping is a mapping for a class having a reference to another class as a
member variable. We have seen such mapping while having two tables and using <set >
element in the mapping file. Now we will use <component> element in the mapping file
and a single table would be used to keep the attributes contained inside the class variable.

Define RDBMS Tables


Consider a situation where we need to store our employee records in EMPLOYEE table ,
which will have the following structure:

177
Hibernate

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Further, assume each employee will have an address, so let us add address specific fields
in the same table as follows:

create table EMPLOYEE (


id INT NOT NULL auto_increment ,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
street_name VARCHAR(40) default NULL,
city_name VARCHAR(40) default NULL,
state_name VARCHAR(40) default NULL,
zipcode VARCHAR(10) default NULL,
PRIMARY KEY (id)
);

Define POJO Classes


Let us implement our POJO class Employee, which will be used to persist the objects
related to EMPLOYEE table.

import java.util.*;

public class Employee implements java.io.Serializable {


private int id;
private String firstName;
private String lastName;
private int salary;
private Address address;

public Employee() {}
public Employee(String fname, String lname,
178
Hibernate

int salary, Address address ) {


this.firstName = fname;
this.lastName = lname;
this.salary = salary;
this.address = address;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}

public Address getAddress() {


return address;
}
public void setAddress( Address address ) {
this.address = address;
179
Hibernate

}
}

We need to define another POJO class corresponding to ADDRESS entity having address
related fields.

import java.util.*;

public class Address{


private int id;
private String street;
private String city;
private String state;
private String zipcode;

public Address() {}
public Address(String street, String city,
String state, String zipcode) {
this.street = street;
this.city = city;
this.state = state;
this.zipcode = zipcode;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet( String street ) {
this.street = street;
}
public String getCity() {
return city;

180
Hibernate

}
public void setCity( String city ) {
this.city = city;
}
public String getState() {
return state;
}
public void setState( String state ) {
this.state = state;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode( String zipcode ) {
this.zipcode = zipcode;
}

Define Hibernate Mapping File


Let us develop our mapping file, which instructs Hibernate how to map the defined classes
to the database tables. The <component > element will be used to define the rule for all
the fields associated with ADDRESS table.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>

181
Hibernate

</id>
<component name="address" class="Address">
<property name="street" column="street_name" type="string"/>
<property name="city" column="city_name" type="string"/>
<property name="state" column="state_name" type="string"/>
<property name="zipcode" column="zipcode" type="string"/>
</component>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>

<class name="Certificate" table="CERTIFICATE">


<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>

</hibernate-mapping>

You should save the mapping document in a file with the format <classname>.hbm. xml.
We saved our mapping document in the file Employee.hbm.xml. You are already familiar
with most of the mapping detail, but let us see all the elements of mapping file once again:

 The mapping document is an XML document having <hibernate-mapping> as


the root element, which contains two <class> elements corresponding to each
class.

 The <class> elements are used to define specific mappings from a Java classes to
the database tables. The Java class name is specified using the name attribute of
the class element and the database table name is specified using the table
attribute.

 The <meta> element is optional element and can be used to create the class
description.

 The <id> element maps the unique ID attribute in class to the primary key of the
database table. The name attribute of the id element refers to the property in the
class and the column attribute refers to the column in the database table. The
182
Hibernate

type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <generator> element within the id element is used to generate the primary
key values automatically. The class attribute of the generator element is set to
native to let hibernate pick up either identity, sequence or hilo algorithm to
create primary key depending upon the capabilities of the underlying database.

 The <property> element is used to map a Java class property to a column in the
database table. The name attribute of the element refers to the property in the
class and the column attribute refers to the column in the database table. The
type attribute holds the hibernate mapping type, this mapping types will convert
from Java to SQL data type.

 The <component> element sets the existence of different attributes of Address


class inside Employee classes.

CreateApplication Class
Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee's records along with their certificates
and then we will apply CRUD operations on those records.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();

/* Let us have one address object */

183
Hibernate

Address address1 = ME.addAddress("Kondapur","Hyderabad","AP","532");

/* Add employee records in the database */


Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, address1);

/* Let us have another address object */


Address address2 = ME.addAddress("Saharanpur","Ambehta","UP","111");

/* Add another employee record in the database */


Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, address2);

/* List down all the employees */


ME.listEmployees();

/* Update employee's salary records */


ME.updateEmployee(empID1, 5000);

/* List down all the employees */


ME.listEmployees();

/* Method to add an address record in the database */


public Address addAddress(String street, String city,
String state, String zipcode) {
Session session = factory.openSession();
Transaction tx = null;
Integer addressID = null;
Address address = null;
try{
tx = session.beginTransaction();
address = new Address(street, city, state, zipcode);
addressID = (Integer) session.save(address);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
184
Hibernate

e.printStackTrace();
}finally {
session.close();
}
return address;
}

/* Method to add an employee record in the database */


public Integer addEmployee(String fname, String lname,
int salary, Address address){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary, address);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to list all the employees detail */


public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
185
Hibernate

Employee employee = (Employee) iterator.next();


System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
Address add = employee.getAddress();
System.out.println("Address ");
System.out.println("\tStreet: " + add.getStreet());
System.out.println("\tCity: " + add.getCity());
System.out.println("\tState: " + add.getState());
System.out.println("\tZipcode: " + add.getZipcode());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
186
Hibernate

}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get the following result on the screen, and same time records would be created
in EMPLOYEE table.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Manoj Last Name: Kumar Salary: 4000


Address
Street: Kondapur
City: Hyderabad
State: AP
Zipcode: 532
First Name: Dilip Last Name: Kumar Salary: 3000
Address
Street: Saharanpur
City: Ambehta
State: UP
Zipcode: 111
First Name: Manoj Last Name: Kumar Salary: 5000
Address
Street: Kondapur
City: Hyderabad
State: AP
Zipcode: 532
First Name: Dilip Last Name: Kumar Salary: 3000

187
Hibernate

Address
Street: Saharanpur
City: Ambehta
State: UP
Zipcode: 111

If you check your EMPLOYEE table, it should have the following records:

mysql> select id, first_name,salary, street_name, state_name from EMPLOYEE;


+----+------------+--------+-------------+------------+
| id | first_name | salary | street_name | state_name |
+----+------------+--------+-------------+------------+
| 1 | Manoj | 5000 | Kondapur | AP |
| 2 | Dilip | 3000 | Saharanpur | UP |
+----+------------+--------+-------------+------------+
2 rows in set (0.00 sec)

mysql>

188
Hibernate
12. HIBERNATE – ANNOTATIONS

So far you have seen how Hibernate uses XML mapping file for the transformation of data
from POJO to database tables and vice versa. Hibernate annotations are the newest way
to define mappings without the use of XML file. You can use annotations in addition to or
as a replacement of XML mapping metadata.

Hibernate Annotations is the powerful way to provide the metadata for the Object and
Relational Table mapping. All the metadata is clubbed into the POJO java file along with
the code, this helps the user to understand the table structure and POJO simultaneously
during the development.

If you going to make your application portable to other EJB 3 compliant ORM applications,
you must use annotations to represent the mapping information, but still if you want
greater flexibility, then you should go with XML-based mappings.

Environment Setup for Hibernate Annotation


First of all you would have to make sure that you are using JDK 5.0 otherwise you need
to upgrade your JDK to JDK 5.0 to take advantage of the native support for annotations.

Second, you will need to install the Hibernate 3.x annotations distribution package,
available from the sourceforge: (Download Hibernate Annotation) and copy hibernate -
annotations.jar, lib/hibernate-comons-annotations. jar and lib/ejb3-
persistence.jar from the Hibernate Annotations distribution to your CLASSPATH.

Annotated Class Example


As I mentioned above while working with Hibernate Annotation, all the metadata is clubbed
into the POJO java file along with the code, this helps the user to understand the table
structure and POJO simultaneously during the development.

Consider we are going to use the following EMPLOYEE table to store our objects:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

189
Hibernate

Following is the mapping of Employee class with annotations to map objects with the
defined EMPLOYEE table:

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id @GeneratedValue
@Column(name = "id")
private int id;

@Column(name = "first_name")
private String firstName;

@Column(name = "last_name")
private String lastName;

@Column(name = "salary")
private int salary;

public Employee() {}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
190
Hibernate

public void setLastName( String last_name ) {


this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}

Hibernate detects that the @Id annotation is on a field and assumes that it should access
properties of an object directly through fields at runtime. If you placed the @Id annotation
on the getId() method, you would enable access to properties through gett er and setter
methods by default. Hence, all other annotations are also placed on either fields or getter
methods, following the selected strategy. Following section will explain the annotations
used in the above class.

@Entity Annotation
The EJB 3 standard annotations are contained in the javax.persistence package, so we
import this package as the first step. Second, we used the @Entity annotation to the
Employee class, which marks this class as an entity bean, so it must have a no-argument
constructor that is visible with at least protected scope.

@Table Annotation
The @Table annotation allows you to specify the details of the table that will be used to
persist the entity in the database.

The @Table annotation provides four attributes, allowing you to ove rride the name of the
table, its catalogue, and its schema, and enforce unique constraints on columns in the
table. For now, we are using just table name, which is EMPLOYEE.

@Id and @GeneratedValue Annotations


Each entity bean will have a primary key, whic h you annotate on the class with the @Id
annotation. The primary key can be a single field or a combination of multiple fields
depending on your table structure.

By default, the @Id annotation will automatically determine the most appropriate primary
key generation strategy to be used but you can override this by applying the
@GeneratedValue annotation, which takes two parameters strategy and generator
that I'm not going to discuss here, so let us use only the default key generation strategy.
Letting Hibernate determine which generator type to use makes your code portable
between different databases.

191
Hibernate

@Column Annotation
The @Column annotation is used to specify the details of the column to which a field or
property will be mapped. You can use column annotation with the following most
commonly used attributes:

 name attribute permits the name of the column to be explicitly specified.

 length attribute permits the size of the column used to map a value particularly
for a String value.

 nullable attribute permits the column to be marked NOT NULL when the schema
is generated.

 unique attribute permits the column to be marked as containing only unique


values.

Create Application Class


Finally, we will create our application class with the main() method to run the application.
We will use this application to save few Employee's records and then we will apply CRUD
operations on those records.

import java.util.List;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new AnnotationConfiguration ().
configure().
//addPackage("com.xyz") //add package if used.
addAnnotatedClass(Employee.class).
buildSessionFactory();

192
Hibernate

}catch (Throwable ex) {


System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();

/* Add few employee records in database */


Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
Integer empID3 = ME.addEmployee("John", "Paul", 10000);

/* List down all the employees */


ME.listEmployees();

/* Update employee's records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down new list of the employees */


ME.listEmployees();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String fname, String lname, int salary){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee();
employee.setFirstName(fname);
employee.setLastName(lname);
employee.setSalary(salary);
employeeID = (Integer) session.save(employee);
tx.commit();
193
Hibernate

}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}
/* Method to READ all the employees */
public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to UPDATE salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
194
Hibernate

Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to DELETE an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Database Configuration
Now let us create hibernate.cfg.xml configuration file to define database related
parameters.

195
Hibernate

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


<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>

<!-- Assume students is the database name -->


<property name="hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<property name="hibernate.connection.username" >
root
</property>
<property name="hibernate.connection.password" >
cohondob
</property>

</session-factory>
</hibernate-configuration>

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Delete
Employee.hbm.xml mapping file from the path.

 Create Employee.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

196
Hibernate

You would get some notification from Hibernate library and the following result, and records
would be created in EMPLOYEE table.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Zara Last Name: Ali Salary: 1000


First Name: Daisy Last Name: Das Salary: 5000
First Name: John Last Name: Paul Salary: 10000
First Name: Zara Last Name: Ali Salary: 5000
First Name: John Last Name: Paul Salary: 10000

If you check your EMPLOYEE table, it should have the following records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara | Ali | 5000 |
| 31 | John | Paul | 10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec

mysql>

197
Hibernate
13. HIBERNATE – QUERY LANGUAGE

Hibernate Query Language (HQL) is an object-oriented query language, similar to SQL,


but instead of operating on tables and columns, HQL works with persistent objects and
their properties. HQL queries are translated by Hibernate into conventional SQL queries ,
which in turns perform action on database.

Although you can use SQL statements directly with Hibernate using Native SQL, but I
would recommend to use HQL whenever possible to avoid database portability hassles,
and to take advantage of Hibernate's SQL generation and caching strategie s.

Keywords like SELECT, FROM, and WHERE, etc., are not case sensitive, but properties like
table and column names are case sensitive in HQL.

FROM Clause
You will use FROM clause if you want to load a complete persistent objects into memory.
Following is the simple syntax of using FROM clause:

String hql = "FROM Employee";


Query query = session.createQuery(hql);
List results = query.list();

If you need to fully qualify a class name in HQL, just specify the package and class name
as follows:

String hql = "FROM com.hibernatebook.criteria.Employee" ;


Query query = session.createQuery(hql);
List results = query.list();

AS Clause
The AS clause can be used to assign aliases to the classes in your HQL queries, especially
when you have the long queries. For instance, our previous simple example would be the
following:

String hql = "FROM Employee AS E";


Query query = session.createQuery(hql);
List results = query.list();

The AS keyword is optional and you can also specify the alias directly after the class name,
as follows:

String hql = "FROM Employee E";


198
Hibernate

Query query = session.createQuery(hql);


List results = query.list();

SELECT Clause
The SELECT clause provides more control over the result set then the from clause. If you
want to obtain few properties of objects instead of the complete object, use the SELECT
clause. Following is the simple syntax of using SELECT clause to get just first_name field
of the Employee object:

String hql = "SELECT E.firstName FROM Employee E" ;


Query query = session.createQuery(hql);
List results = query.list();

It is notable here that Employee.firstName is a property of Employee object rather than


a field of the EMPLOYEE table.

WHERE Clause
If you want to narrow the spec ific objects that are returned from storage, you use the
WHERE clause. Following is the simple syntax of using WHERE clause:

String hql = "FROM Employee E WHERE E.id = 10" ;


Query query = session.createQuery(hql);
List results = query.list();

ORDER BY Clause
To sort your HQL query's results, you will need to use the ORDER BY clause. You can
order the results by any property on the objects in the result set either ascending (ASC)
or descending (DESC). Following is the simple syntax of using ORDER BY clause:

String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";
Query query = session.createQuery(hql);
List results = query.list();

If you wanted to sort by more than one property, you would just add the additional
properties to the end of the order by clause, separated by commas as follows:

String hql = "FROM Employee E WHERE E.id > 10 " +


"ORDER BY E.firstName DESC, E.salary DESC ";
Query query = session.createQuery(hql);
List results = query.list();

199
Hibernate

GROUP by Clause
This clause lets Hibernate pull information from the database and group it based on a value
of an attribute and, typically, use the result to include an aggregate value. Following is the
simple syntax of using GROUP BY clause:

String hql = "SELECT SUM(E.salary), E.firtN ame FROM Employee E " +


"GROUP BY E.firstName";
Query query = session.createQuery(hql);
List results = query.list();

Using Named Parameters


Hibernate supports named parameters in its HQL queries. This makes writing HQL queries
that accept input from the user easy and you do not have to defend against SQL injection
attacks. Following is the simple syntax of using named parameters:

String hql = "FROM Employee E WHERE E.id = :employee_id";


Query query = session.createQuery(hql);
query.setParameter("employee_id",10);
List results = query.list();

UPDATE Clause
Bulk updates are new to HQL with Hibernate 3, and delete work differently in Hibernate 3
than they did in Hibernate 2. The Query interface now contains a method called
executeUpdate() for executing HQL UPDATE or DELETE statements.

The UPDATE clause can be used to update one or more properties of an one or more
objects. Following is the simple syntax of using UPDATE clause:

String hql = "UPDATE Employee set salary = :salary " +


"WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("salary", 1000);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

200
Hibernate

DELETE Clause
The DELETE clause can be used to delete one or more objects. Following is the simple
syntax of using DELETE clause:

String hql = "DELETE FROM Employee " +


"WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

INSERT Clause
HQL supports INSERT INTO clause only where records can be inserted from one object
to another object. Following is the simple syntax of using INSERT INTO clause:

String hql = "INSERT INTO Employee(firstName, lastName, salary)" +


"SELECT firstName, lastName, salary FROM old_employee" ;
Query query = session.createQuery(hql);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

Aggregate Methods
HQL supports a range of aggregate methods, similar to SQL. They work the same way in
HQL as in SQL and following is the list of the available functions:

S.N. Functions Description


1 avg(property name) The average of a property's value
The number of times a property occurs in the
2 count(property name or *)
results
3 max(property name) The maximum value of the property values
4 min(property name) The minimum value of the property values
5 sum(property name) The sum total of the property values

The distinct keyword only counts the unique values in the row set. The following query
will return only unique count:

String hql = "SELECT count(distinct E.firstName) FROM Employee E";


Query query = session.createQuery(hql);

201
Hibernate

List results = query.list();

Pagination using Query


There are two methods of the Query interface for pagination.

S.N. Method & Description


Query setFirstResult(int startPosition)
1 This method takes an integer that represents the first row in your result set,
starting with row 0.

Query setMaxResults(int maxResult)


2
This method tells Hibernate to retrieve a fixed number maxResults of objects.

Using above two methods together, we can construct a paging component in our web or
Swing application. Following is the example, which you can extend to fetch 10 rows at a
time:

String hql = "FROM Employee";


Query query = session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(10);
List results = query.list();

202
Hibernate
14. HIBERNATE – CRITERIA QUERIES

Hibernate provides alternate ways of manipulating objects and in turn data available in
RDBMS tables. One of the methods is Criteria API, which allows you to build up a criteria
query object programmatically where you can apply filtration rules and logical conditions.

The Hibernate Session interface provides createCriteria() method, which can be used
to create a Criteria object that returns instances of the persistence object's class when
your application executes a criteria query.

Following is the simplest example of a criteria query is one, which will simply return every
object that corresponds to the Employee class.

Criteria cr = session.createCriteria(Employee.class);
List results = cr.list();

Restrictions with Criteria


You can use add() method available for Criteria object to add restriction for a criteria
query. Following is the example to add a restriction to return the records with salary is
equal to 2000:

Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq("salary", 2000));
List results = cr.list();

Following are the few more examples covering different scenarios and can be used as per
the requirement:

Criteria cr = session.createCriteria(Employee.class);

// To get records having salary more than 2000


cr.add(Restrictions.gt("salary", 2000));

// To get records having salary less than 2000


cr.add(Restrictions.lt("salary", 2000));

// To get records having fistName starting with zara


cr.add(Restrictions.like("firstName", "zara%"));

// Case sensitive form of the above restriction.

203
Hibernate

cr.add(Restrictions.ilike("firstName", "zara%"));

// To get records having salary in between 1000 and 2000


cr.add(Restrictions.between("salary", 1000, 2000));

// To check if the given property is null


cr.add(Restrictions.isNull("salary"));

// To check if the given property is not null


cr.add(Restrictions.isNotNull("salary"));

// To check if the given property is empty


cr.add(Restrictions.isEmpty("salary"));

// To check if the given property is not empty


cr.add(Restrictions.isNotEmpty("salary"));

You can create AND or OR conditions using LogicalExpression restrictions as follows:

Criteria cr = session.createCriteria(Employee.class);

Criterion salary = Restrictions.gt("salary", 2000);


Criterion name = Restrictions.ilike("firstNname","zara%");

// To get records matching with OR condistions


LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );
// To get records matching with AND condistions
LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );
List results = cr.list();

204
Hibernate

Pagination Using Criteria


There are two methods of the Criteria interface for pagination.

S.N. Method & Description

public Criteria setFirstResult(int firstResult)


1 This method takes an integer that represents the first row in your result set,
starting with row 0.

public Criteria setMaxResults(int maxResults)


2
This method tells Hibernate to retrieve a fixed number maxResults of objects.

Using above two methods together, we can construct a paging component in our web or
Swing application. Following is the example, which you can extend to fetch 10 rows at a
time:

Criteria cr = session.createCriteria(Employee.class);
cr.setFirstResult(1);
cr.setMaxResults(10);
List results = cr.list();

Sorting the Results


The Criteria API provides the org.hibernate.criterion.Orde r class to sort your result set
in either ascending or descending order, according to one of your object's properties. This
example demonstrates how you would use the Order class to sort the result set:

Criteria cr = session.createCriteria(Employee.class);
// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));

// To sort records in descening order


crit.addOrder(Order.desc("salary"));

// To sort records in ascending order


crit.addOrder(Order.asc("salary"));
List results = cr.list();

Projections & Aggregations


The Criteria API provides the org.hibernate.criterion. Projections class, which can be
used to get average, maximum, or minimum of the property values. The Projections class
205
Hibernate

is similar to the Restrictions class, in that it provides several static factory methods for
obtaining Projection instances.

Following are the few examples covering different scenarios and can be us ed as per
requirement:

Criteria cr = session.createCriteria(Employee.class);

// To get total row count.


cr.setProjection(Projections.rowCount());

// To get average of a property.


cr.setProjection(Projections.avg("salary"));

// To get distinct count of a property.


cr.setProjection(Projections.countDistinct("firstName"));

// To get maximum of a property.


cr.setProjection(Projections.max("salary"));

// To get minimum of a property.


cr.setProjection(Projections.min("salary"));

// To get sum of a property.


cr.setProjection(Projections.sum("salary"));

Criteria Queries Example


Consider the following POJO class:

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;

206
Hibernate

this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}

Let us create the following EMPLOYEE table to store Employee objects:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
207
Hibernate

);

Following will be the mapping file.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>

Finally, we will create our application class with the main() method to run the application
where we will use Criteria queries:

import java.util.List;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Projections;
import org.hibernate.cfg.Configuration;

208
Hibernate

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();

/* Add few employee records in database */


Integer empID1 = ME.addEmployee("Zara", "Ali", 2000);
Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
Integer empID3 = ME.addEmployee("John", "Paul", 5000);
Integer empID4 = ME.addEmployee("Mohd", "Yasee", 3000);

/* List down all the employees */


ME.listEmployees();

/* Print Total employee's count */


ME.countEmployee();

/* Print Toatl salary */


ME.totalSalary();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String fname, String lname, int salary){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employeeID = (Integer) session.save(employee);
209
Hibernate

tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to READ all the employees having salary more than 2000 */
public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Employee.class);
// Add restriction.
cr.add(Restrictions.gt("salary", 2000));
List employees = cr.list();

for (Iterator iterator =


employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
210
Hibernate

/* Method to print total number of records */


public void countEmployee(){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Employee.class);

// To get total row count.


cr.setProjection(Projections.rowCount());
List rowCount = cr.list();

System.out.println("Total Coint: " + rowCount.get(0) );


tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to print sum of salaries */
public void totalSalary(){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Employee.class);

// To get total salary.


cr.setProjection(Projections.sum("salary"));
List totalSalary = cr.list();

System.out.println("Total Salary: " + totalSalary.get(0) );


tx.commit();
}catch (HibernateException e) {
211
Hibernate

if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get some notifications from hibernate library, the following result, and records
would be created in the EMPLOYEE table.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Daisy Last Name: Das Salary: 5000


First Name: John Last Name: Paul Salary: 5000
First Name: Mohd Last Name: Yasee Salary: 3000
Total Coint: 4
Total Salary: 15000

If you check your EMPLOYEE table, it should have the following records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 14 | Zara | Ali | 2000 |
| 15 | Daisy | Das | 5000 |
| 16 | John | Paul | 5000 |

212
Hibernate

| 17 | Mohd | Yasee | 3000 |


+----+------------+-----------+--------+
4 rows in set (0.00 sec)
mysql>

213
Hibernate
15. HIBERNATE – NATIVE SQL

You can use native SQL to express database queries if you want to utilize database -specific
features such as query hints or the CONNECT keyword in Oracle. Hibernate 3.x allows you
to specify handwritten SQL, including stored procedures, for all create, update, delete, and
load operations.

Your application will create a native SQL query from the session with the
createSQLQuery() method on the Session interface.:

public SQLQuery createSQLQuery(String sqlString) throws HibernateException

After you pass a string containing the SQL query to the createSQLQuery() method, you
can associate the SQL result with either an existing Hibernate entity, a join, or a scalar
result using addEntity(), addJoin(), and addScalar() methods respectively.

Scalar Queries
The most basic SQL query is to get a list of scalars (values) from one or more tables.
Following is the syntax for using native SQL for sc alar values:

String sql = "SELECT first_name, salary FROM EMPLOYEE";


SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();

Entity Queries
The above queries were all about returning scalar values, basically returning the "raw "
values from the result set. Following is the syntax to get entity objects as a whole from a
native sql query via addEntity().

String sql = "SELECT * FROM EMPLOYEE";


SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
List results = query.list();

Named SQL Queries


Following is the syntax to get entity objects from a native sql query via addEntity() and
using named SQL query.

String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id";


214
Hibernate

SQLQuery query = session.createSQLQuery(sql);


query.addEntity(Employee.class);
query.setParameter("employee_id", 10);
List results = query.list();

Native SQL Example


Consider the following POJO class:

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
215
Hibernate

this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}

Let us create the following EMPLOYEE table to store Employee objects:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Following will be the mapping file:

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
216
Hibernate

</class>
</hibernate-mapping>

Finally, we will create our application class with the main() method to run the application
where we will use Native SQL queries:

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.SQLQuery;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();

/* Add few employee records in database */


Integer empID1 = ME.addEmployee("Zara", "Ali", 2000);
Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
Integer empID3 = ME.addEmployee("John", "Paul", 5000);
Integer empID4 = ME.addEmployee("Mohd", "Yasee", 3000);

/* List down employees and their salary using Scalar Query */


ME.listEmployeesScalar();

217
Hibernate

/* List down complete employees information using Entity Query */


ME.listEmployeesEntity();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String fname, String lname, int salary){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}

/* Method to READ all the employees using Scalar Query */


public void listEmployeesScalar( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
String sql = "SELECT first_name, salary FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List data = query.list();

for(Object object : data)


{
Map row = (Map)object;
218
Hibernate

System.out.print("First Name: " + row.get("first_name"));


System.out.println(", Salary: " + row.get("salary"));
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}

/* Method to READ all the employees using Entity Query */


public void listEmployeesEntity( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
String sql = "SELECT * FROM EMPLOYEE" ;
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
List employees = query.list();

for (Iterator iterator =


employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
219
Hibernate

}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get the following result, and records would be created in the EMPLOYEE table.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Zara, Salary: 2000


First Name: Daisy, Salary: 5000
First Name: John, Salary: 5000
First Name: Mohd, Salary: 3000
First Name: Zara Last Name: Ali Salary: 2000
First Name: Daisy Last Name: Das Salary: 5000
First Name: John Last Name: Paul Salary: 5000
First Name: Mohd Last Name: Yasee Salary: 3000

If you check your EMPLOYEE table, it should have the following records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 26 | Zara | Ali | 2000 |
| 27 | Daisy | Das | 5000 |
| 28 | John | Paul | 5000 |
| 29 | Mohd | Yasee | 3000 |
+----+------------+-----------+--------+
220
Hibernate

4 rows in set (0.00 sec)


mysql>

221
Hibernate
16. HIBERNATE – CACHING

Caching is all about application performance optimization and it sits between your application and
the database to avoid the number of database hits as many as possible to give a better
performance for performance critical applications.

Caching is important to Hibernate as well. It utilizes a multilevel caching scheme as


explained below:

First-level Cache
The first-level cache is the Session cache and is a mandatory cache through which all
requests must pass. The Session object keeps an object under its own pow er before
committing it to the database.

If you issue multiple updates to an object, Hibernate tries to delay doing the update as
long as possible to reduce the number of update SQL statements issued. If you close the
session, all the objects being cached are lost and either persisted or updated in the
database.

222
Hibernate

Second-level Cache
Second level cache is an optional cache and first -level cache will always be consulted
before any attempt is made to locate an object in the second-level cache. The second-
level c ache can be configured on a per-class and per-collection basis and mainly
responsible for caching objects across sessions.

Any third-party cache can be used with Hibernate. An


org.hibernate.cache.CacheProvider interface is provided, which must be implement ed
to provide Hibernate with a handle to the cache implementation.

Query-level Cache
Hibernate also implements a cache for query resultsets that integrates closely with the
second-level cache.

This is an optional feature and requires two additional physical cache regions that hold the
cached query results and the timestamps when a table was last updated. This is only useful
for queries that are run frequently with the same parameters.

The Second Level Cache


Hibernate uses first-level cache by default and you have nothing to do to use first -level
cache. Let's go straight to the optional second-level cache. Not all classes benefit from
caching, so it's important to be able to disable the second-level cache.

The Hibernate second-level cache is set up in two steps. First, you have to decide which
concurrency strategy to use. After that, you configure cache expiration and physical cache
attributes using the cache provider.

Concurrency Strategies
A concurrency strategy is a mediator, which is responsible for storing items of data in the
cache and retrieving them from the cache. If you are going to enable a second-level cache,
you will have to decide, for each persistent class and collection, which cache concurrency
strategy to use.

 Transactional: Use this strategy for read-mostly data where it is critical to prevent
stale data in concurrent transactions, in the rare case of an update.

 Read-write: Again use this strategy for read-mostly data where it is critical to
prevent stale data in concurrent transactions, in the rare case of an update.

 Nonstrict-read-write: This strategy makes no guarantee of consistency between


the cache and the database. Use this strategy if data hardly ever changes and a
small likelihood of stale data is not of critical concern.

 Read-only: A concurrency strategy suitable for data, which never changes. Use it
for reference data only.

If we are going to use second-level caching for our Employee class, let us add the
mapping element required to tell Hibernate to cache Employee instances using read-
write strategy.
223
Hibernate

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<cache usage="read-write"/>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>

The usage="read-write" attribute tells Hibernate to use a read-write concurrency strategy


for the defined cache.

Cache Provider
Your next step after considering the concurrency strategies , you will use your cache
candidate classes to pick a cache provider. Hibernate forces you to choose a s ingle cache
provider for the whole application.

S.N. Cache Name Description

It can cache in memory or on disk and clustered caching and it


1 EHCache
supports the optional Hibernate query result cache.

Supports caching to memory and disk in a single JVM with a


2 OSCache
rich set of expiration policies and query cache support.
A cluster cache based on JGroups. It uses clustered
3 warmCache
invalidation, but doesn't support the Hibernate query cache.
A fully transactional replicated clustered cache also based on
the JGroups multicast library. It supports replication or
4 JBoss Cache invalidation, synchronous or asynchronous communication, and
optimistic and pessimistic locking. The Hibernate query cache is
supported.

224
Hibernate

Every cache provider is not compatible with every concurrency strategy. The following
compatibility matrix will help you choose an appropriate combination.

Read- Nonstrictread- Read-


Strategy/Provider Transactional
only write write

EHCache X X X
OSCache X X X
SwarmCache X X
JBoss Cache X X

You will specify a cache provider in hibernate.cfg.xml configuration file. We choose


EHCache as our second-level cache provider:

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


<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_cl ass">
com.mysql.jdbc.Driver
</property>

<!-- Assume students is the database name -->


<property name="hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<property name="hibernate.connection.username" >
root
</property>
<property name="hibernate.connection.password" >
root123
</property>
<property name="hibernate.cache.provider_class">
225
Hibernate

org.hibernate.cache.EhCacheProvider
</property>

<!-- List of XML mapping files -->


<mapping resource="Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

Now, you need to specify the properties of the cache regions. EHCache has its own
configuration file, ehcache.xml, which should be in the CLASSPATH of the application. A
cache configuration in ehcache.xml for the Employee class may look like this:

<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>

<cache name="Employee"
maxElementsInMemory="500"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/>

That's it, now we have second-level caching enabled for the Employee class and Hibernate ,
now hits the second-level cache whenever you navigate to an Employee or when you load
an Employee by identifier.

You should analyze your all the classes and choose appropriate caching strategy for each
of the classes. Sometime, second-level caching may downgrade the performance of the
application. So, it is recommended to benchmark your application first , without enabling
caching and later on enable your well suited caching and check the performance. If caching
is not improving system performance, then there is no point in enabling any type of
caching.

226
Hibernate

The Query-level Cache


To use the query cache, you must first activate it using the
hibernate.cache.use_query_cache = "true" property in the configuration file. By
setting this property to true, you make Hibernate create the necessary caches in memory
to hold the query and identifier sets.

Next, to use the query cache, you use the setCacheable(Boolean) method of the Query
class. For example:

Session session = SessionFactory.openSession();


Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate also supports very fine-grained cache support through the concept of a cache
region. A cache region is part of the cache that's given a name.

Session session = SessionFactory.openSession();


Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

This code uses the method to tell Hibernate to store and look for the query in the employee
area of the cache.

227
Hibernate
17. HIBERNATE – BATCH PROCESSING

Consider a situation when you need to upload a large number of records into your database
using Hibernate. Following is the code snippet to achieve this using Hibernate:

Session session = SessionFactory.openSession();


Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Employee employee = new Employee(.....);
session.save(employee);
}
tx.commit();
session.close();

By default, Hibernate will cache all the persisted objects in the session-level cache and
ultimately your application would fall over with an OutOfMemoryException somewhere
around the 50,000th row. You can resolve this problem, if you are using batch processing
with Hibernate.

To use the batch processing feature, first set hibernate.jdbc.batch_size as batch size
to a number either at 20 or 50 depending on object size. This will tell the hibernat e
container that every X rows to be inserted as batch. To implement this in your code, we
would need to do little modification as follows:

Session session = SessionFactory.openSession();


Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Employee employee = new Employee(.....);
session.save(employee);
if( i % 50 == 0 ) { // Same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();

Above code will work fine for the INSERT operation, but if you are willing to make UPDAT E
operation, then you can achieve using the following code:
228
Hibernate

Session session = sessionFactory.openSession();


Transaction tx = session.beginTransaction();

ScrollableResults employeeCursor = session.createQuery("FROM EMPLOYEE")


.scroll();
int count = 0;

while ( employeeCursor.next() ) {
Employee employee = (Employee) employeeCursor.get(0);
employee.updateEmployee();
seession.update(employee);
if ( ++count % 50 == 0 ) {
session.flush();
session.clear();
}
}
tx.commit();
session.close();

Batch Processing Example


Let us modify the configuration file to add hibernate.jdbc.batch_size property:

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


<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>

<!-- Assume students is the database name -->


229
Hibernate

<property name="hibernate.connection.url">
jdbc:mysql://localhost/test
</property>
<property name="hibernate.connection.username" >
root
</property>
<property name="hibernate.connection.password" >
root123
</property>
<property name="hibernate.jdbc.batch_size">
50
</property>

<!-- List of XML mapping files -->


<mapping resource="Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

Consider the following POJO Employee class:

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
230
Hibernate

this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
}

Let us create the following EMPLOYEE table to store the Employee objects:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Following will be the mapping file to map the Employee objects with EMPLOYEE table:

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
231
Hibernate

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>

Finally, we will create our application class with the main() method to run the application
where we will use flush() and clear() methods available with Session object so that
Hibernate keeps writing these records into the database inst ead of caching them in the
memory.

import java.util.*;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}
ManageEmployee ME = new ManageEmployee();
232
Hibernate

/* Add employee records in batches */


ME.addEmployees( );
}
/* Method to create employee records in batches */
public void addEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
String fname = "First Name " + i;
String lname = "Last Name " + i;
Integer salary = i;
Employee employee = new Employee(fname, lname, salary);
session.save(employee);
if( i % 50 == 0 ) {
session.flush();
session.clear();
}
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return ;
}
}

233
Hibernate

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained above.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program, which will create 100000
records in EMPLOYEE table.

234
Hibernate
18. HIBERNATE – INTERCEPTORS

As you have learnt that in Hibernate, an object will be created and persisted. Once the
object has been changed, it must be saved back to the database. This process continues
until the next time the object is needed, and it will be loaded from the persistent store.

Thus an object passes through different stages in its life cycle and Interceptor Interfa c e
provides methods, which can be called at different stages to perform some required tasks.
These methods are callbacks from the session to the application, allowing the application
to inspec t and/or manipulate properties of a persistent object before it is saved, updated,
deleted or loaded. Following is the list of all the methods available within the Interceptor
interface:

S.N. Method and Description

findDirty()
1
This method is be called when the flush() method is called on a Session object.

instantiate()
2
This method is called when a persisted class is instantiated.
isUnsaved()
3 This method is called when an object is passed to the saveOrUpdate()
method/
onDelete()
4
This method is called before an object is deleted.
onFlushDirty()
5 This method is called when Hibernate detects that an object is dirty (i.e. have
been changed) during a flush i.e. update operation.
onLoad()
6
This method is called before an object is initialized.
onSave()
7
This method is called before an object is saved.
postFlush()
8 This method is called after a flush has occurred and an object has been updated
in memory.
preFlush()
9
This method is called before a flush.

Hibernate Interceptor gives us total control over how an object will look to both the
application and the database.

235
Hibernate

How to Use Interceptors?


To build an interceptor, you can either implement Interceptor class directly or extend
EmptyInterceptor class. Following will be the simple steps to use Hibernate Interceptor
functionality.

Create Interceptors
We will extend EmptyInterceptor in our example where Interceptor's method will be called
automatically when Employee object is created and updated. You can implement more
methods as per your requirements.

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;
public class MyInterceptor extends EmptyInterceptor {
private int updates;
private int creates;
private int loads;

public void onDelete(Object entity,


Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
// do nothing
}

// This method is called when Employee object gets updated.


public boolean onFlushDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {

236
Hibernate

if ( entity instanceof Employee ) {


System.out.println("Update Operation");
return true;
}
return false;
}
public boolean onLoad(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
// do nothing
return true;
}
// This method is called when Employee object gets created.
public boolean onSave(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
if ( entity instanceof Employee ) {
System.out.println("Create Operation");
return true;
}
return false;
}
//called before commit into database
public void preFlush(Iterator iterator) {
System.out.println("preFlush");
}
//called after committed into database
public void postFlush(Iterator iterator) {
System.out.println("postFlush");
}
}

237
Hibernate

Create POJO Classes


Now, let us modify a little bit our first example where we used EMPLOYEE table and
Employee class to play with:

public class Employee {


private int id;
private String firstName;
private String lastName;
private int salary;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;

238
Hibernate

}
public void setSalary( int salary ) {
this.salary = salary;
}
}

Create Database Tables


Second step would be creating tables in your database. There would be one table
corresponding to each object, you are willing to provide persistence. Consider the objects
explained above, need to be stored and retrieved into the following RDBMS table:

create table EMPLOYEE (


id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);

Create Mapping Configuration File


This step is to create a mapping file that instructs Hibernate — how to map the defined
class or classes to the database tables.

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


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate -mapping-3.0.dtd">

<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="firstName" column="first_name" type="string"/>
239
Hibernate

<property name="lastName" column="last_name" type="string"/>


<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>

Create Application Class


Finally, we will create our application class with the main() method to run the application.
Here, it should be noted that while creating session object , we used our Interceptor class
as an argument.

import java.util.List;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {


private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError (ex);
}

ManageEmployee ME = new ManageEmployee();

/* Add few employee records in database */


Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
Integer empID3 = ME.addEmployee("John", "Paul", 10000);

240
Hibernate

/* List down all the employees */


ME.listEmployees();

/* Update employee's records */


ME.updateEmployee(empID1, 5000);

/* Delete an employee from the database */


ME.deleteEmployee(empID2);

/* List down new list of the employees */


ME.listEmployees();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String fname, String lname, int salary){
Session session = factory.openSession( new MyInterceptor() );
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}
/* Method to READ all the employees */
public void listEmployees( ){
Session session = factory.openSession( new MyInterceptor() );
Transaction tx = null;
try{
241
Hibernate

tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to UPDATE salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession( new MyInterceptor() );
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to DELETE an employee from the records */
242
Hibernate

public void deleteEmployee(Integer EmployeeID){


Session session = factory.openSession( new MyInterceptor() );
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Compilation and Execution


 Here are the steps to compile and run the above mentioned application using Eclipse
IDE. Make sure that all the required jars are added to the project. Create
hibernate.cfg.xml configuration file as explained in configuration chapter.

 Create Employee.hbm.xml mapping file as shown above.

 Create Employee.java source file as shown above and compile it.

 Create MyInterceptor.java source file as shown above and compile it.

 Create ManageEmployee.java source file as shown above and compile it.

 Execute ManageEmployee binary to run the program.

You would get the following result, and records would be created in the EMPLOYEE table.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

Create Operation
preFlush
postFlush

243
Hibernate

Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
First Name: Zara Last Name: Ali Salary: 1000
First Name: Daisy Last Name: Das Salary: 5000
First Name: John Last Name: Paul Salary: 10000
preFlush
postFlush
preFlush
Update Operation
postFlush
preFlush
postFlush
First Name: Zara Last Name: Ali Salary: 5000
First Name: John Last Name: Paul Salary: 10000
preFlush
postFlush

If you check your EMPLOYEE table, it should have the following records:

mysql> select * from EMPLOYEE;


+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara | Ali | 5000 |
| 31 | John | Paul | 10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec
mysql>

244

You might also like