Sie sind auf Seite 1von 105

Hibernate

What is Hibernate ?

Hibernate is an object-relational mapping (ORM) library for the


Java language.
Providing a framework for mapping an object-oriented domain model
to a traditional relational database
Hibernate's primary feature is mapping from Java classes to database tables (and

from Java data types to SQL data types)


Mapping Java classes to database tables is accomplished through the
configuration of an XML file or by using Java Annotations
Hibernate can use the XML file or the annotations to maintain the
database schema.
Hibernate is an object-relational mapping tool, a persistence
framework and is used to persist Java objects in a relational
database

Hibernate is an ORM, so you can use either struts+hibernate or


spring+hibernate to build a web application.

In the hibernate u need not bother about how to create table in SQL and u need not
to remember connection, prepared statement like that data is stored in persistence
way in data base. It makes developer life easy

It also provides data query and retrieval facilities

Hibernate Architecture :
Hibernate:
1) Itself opens connection to database,
2) Converts HQL (Hibernate Query Language) statements to database
specific statement,
3) Receives result set,
4) Then performs mapping of these database specific data to Java objects
which are directly used by Java application.

Hibernate uses the database specification from Hibernate Properties


file.
Automatic mapping is performed on the basis of the properties
defined in hbm XML file defined for particular Java object

Hibernate
Hibernate communication with RDBMS :

Load the Hibernate configuration file (.cfg) and create configuration


object. It will automatically load all hbm mapping files.

Create session factory from configuration object

Get one session from this session factory.

Create HQL query.

Execute query to get list containing Java objects.

Example,
Retrieve list of employees from Employee table using Hibernate.
/* Load the hibernate configuration file */
Configuration cfg = new Configuration();
cfg.configure(CONFIG_FILE_LOCATION);
/* Create the session factory */
SessionFactory sessionFactory = cfg.buildSessionFactory();

/* Retrieve the session */


Session session = sessionFactory.openSession();
/* create query */
Query query = session.createQuery("from EmployeeBean);
/* execute query and get result in form of Java objects */
List<EmployeeBean> finalList = query.list();
EmployeeBean.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC

Hibernate
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.mf.bean.EmployeeBean" table="t_employee">
<id name="id" type="string" unsaved-value="null">
<column name="id" sql-type="varchar(32)" not-null="true"/>
<generator class="uuid"/>
</id>
<property name="name">
<column name="name" />
</property>
<property name="salary">
<column name="salary" />
</property>
</class>
</hibernate-mapping>

Why is Hibernate better than JDBC ?


1) Relational Persistence for JAVA

Working with both Object-Oriented software and Relational Database


is complicated task with JDBC because there is mismatch between how
data is represented in objects versus relational database.
So with JDBC, developer has to write code to map an object model's
data representation to a relational data model and its
corresponding database schema.
Hibernate is flexible and powerful ORM solution to map Java classes to
database tables. Hibernate itself takes care of this mapping using
XML files so developer does not need to write code for this.

2) Transparent Persistence

The automatic mapping of Java objects with database tables and vice versa is
called Transparent Persistence.
Hibernate provides transparent persistence and developer does not
need to write code explicitly to map database tables tuples to
application objects during interaction with RDBMS.

Hibernate

With JDBC this conversion is to be taken care of by the developer


manually with lines of code.

3) Support for Query Language

JDBC supports only native Structured Query Language (SQL).


Developer has to find out the efficient way to access database, ie
to select effective query from a number of queries to perform
same task.
Hibernate provides a powerful query language Hibernate Query Language
(independent from type of database) that is expressed in a familiar
SQL like syntax and includes full support for polymorphic queries.
Hibernate also supports native SQL statements. It also selects
an effective way to perform a database manipulation task for an
application.

4) Database Dependent Code

Application using JDBC to handle persistent data (database tables)


having database specific code in large amount.
The code written to map table data to application objects and vice
versa is actually to map table fields to object properties.
As table changed or database changed then its essential to change
object structure as well as to change code written to map
table-to-object/object-to-table.
Hibernate provides this mapping itself. The actual mapping between
tables and application objects is done in XML files.
If there is change in Database or in any table then the only need
to change XML file properties.

5) Maintenance Cost

With JDBC, it is developers responsibility to handle JDBC result set and convert it
to Java objects through code to use this persistent data in application.
So with JDBC, mapping between Java objects and database tables is
done manually.
Hibernate reduces lines of code by maintaining object-table mapping itself and
returns result to application in form of Java objects.
It relieves programmer from manual handling of persistent data,
hence reducing the development time and maintenance cost.

6) Open-Source, Zero-Cost Product License

Hibernate is an open source and free to use for both development


and production deployments.

Disadvantages of Hibernate :

Anybody wanting to maintain application using Hibernate will need


to know Hibernate.

Hibernate

For complex data, mapping from Object-to-tables and vise versa


reduces performance and increases time of conversion.
Hibernate does not allow some type of queries which are supported by JDBC. For
example It does not allow to insert multiple objects (persistent data) to same
table using single query.
Developer has to write separate query to insert each object.

Hibernate vs JDBC :
Hibernate
Hibernate

JDBC

data base independent, In case of JDBC query must be data

is

same code will work for all data base specific


bases like ORACLE,MySQL ,SQLServer
etc.
As

Hibernate is set of Objects

you In case of JDBC you need to learn SQL.

don't need to learn SQL language. You


can treat TABLE as a Object .
Don't need Query tuning

in

case

of In case of JDBC you need to tune your

Hibernate. If you use Criteria Queries queries.


in

Hibernate

then

hibernate

automatically tuned your query and return


best result with performance.
You will get benefit of Cache. Hibernate In case of JDBC you need to implement
support two level of cache. First your JAVA cache .
level

and

2nd

level.

So

you

can

store your data into Cache for better


performance.
Hibernate supports Query cache and It JDBC

doest

Not

provide

any

will provide the statistics about statistics.


your query and database status.
Development fast in case of Hibernate
because

you

don't

need

to

write

queries.
No need to create any connection pool in In case of JDBC you need to write your
case

of

Hibernate.

You

can

use own connection pool.

c3p0.
In the XML file you can see all the
relations between tables in case of

Hibernate
Hibernate. Easy readability.
You can load your objects on start up JDBC Don't have such support.
using

lazy=false

in

case

of

Hibernate.
Hibernate Supports automatic versioning JDBC Does Not Support it.
of rows

Advantages of hibernates:
1.Hibernate supports Inheritance, Associations, Collections
2.In hibernate if we save the derived class object, then its base class object will also be
stored into the database, it means hibernate supporting inheritance
3. Hibernate supports relationships like One-To-Many, One-To-One,
Many-To-Many, Many-To-One
4. This will also supports collections like List, Set, Map (Only new
collections)
5. In JDBC all exceptions are checked exceptions, so we must write code in try,
catch and throws, but in hibernate we only have Unchecked exceptions, so no need
to write try, catch, or no need to write throws. Actually in hibernate we
have the translator which converts checked to Unchecked
6. Hibernate has capability to generate primary keys automatically while we are
storing the records into database
7. Hibernate has its own query language, i.e hibernate query language which
is database independent So if we change the database, then also our
application will works as HQL is database independent
8. HQL contains database independent commands While we are inserting any
record, if we dont have any particular table in the database, JDBC will
rises an error like View not exist, and throws exception, but in case
of hibernate, if it not found any table in the database this will create the table for us.
9. Hibernate supports caching mechanism by this, the number of round trips
between an application and the database will be reduced, by using this
caching technique an application performance will be increased automatically.
10. Hibernate supports annotations, apart from XML
11. Hibernate provided Dialect classes, so we no need to write SQL queries in
hibernate, instead we use the methods provided by that API.
12. Getting pagination in hibernate is quite simple.

Hibernate
13. Hibernate takes care of mapping Java classes to database tables using XML files
and without writing any line of code.
14. Provides simple APIs for storing and retrieving Java objects directly to
and from the database.
15. If there is change in Database or in any table then the only need to change XML file
properties.
16. Provides Simple querying of data.

What is Hibernate ?

Hibernate is an Object-Relational Mapping(ORM) solution for JAVA


and it raised as an open source persistent framework created by Gavin King
in 2001.

It is a powerful, high performance 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.

Hibernate sits between traditional Java objects and database server


to handle all the work in persisting those objects based on the
appropriate O/R mechanisms and patterns.

Supported Databases:
Hibernate supports almost all the major RDBMS. Following is list of few
of the database engines supported by Hibernate.

HSQL Database Engine


DB2/NT
MySQL
PostgreSQL
FrontBase
Oracle
Microsoft SQL Server Database
Sybase SQL Server
Informix Dynamic Server

Hibernate
Supported Technologies:
Hibernate supports
following:

variety

of

other

technologies,

including

the

XDoclet Spring
J2EE
Eclipse plug-ins
Maven

Hibernate Application Architecture :


High Level View

Detailed View

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

The Configuration object is the first Hibernate object you create


in any Hibernate application and usually created only once during
application initialization.

It represents a configuration or properties file required by the


Hibernate.

The Configuration object provides two keys components:


1) Database Connection This is handled through one or more configuration
files supported by Hibernate. These files are hibernate.properties and
hibernate.cfg.xml
2) Class Mapping Setup This component creates the connection between the

Hibernate
Java classes and database tables.
SessionFactory Object:

Configuration object is used to create a SessionFactory object


which in turn configures Hibernate for the application using the
supplied configuration file and allows for a Session object to be
instantiated.

The SessionFactory is a thread safe object and used by all the threads
of an application.

The SessionFactory is heavyweight object so usually it is created


during application start up and kept for later use.

You would need one SessionFactory object per database using a separate
configuration file.

So if you are using multiple databases then you would have to create
multiple SessionFactory objects.

Session Object:

A Session is used to get a physical connection with a database.

The Session object is lightweight and designed to be instantiated


each time an interaction is needed with the database.

Persistent
object.

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

objects

are

saved

and

retrieved

through

Session

Transaction Object:

A Transaction represents a unit of work with the database and most of the
RDBMS supports transaction functionality.

Transactions in Hibernate are handled by an underlying transaction


manager and transaction (from JDBC or JTA).

This is an optional object and Hibernate applications may choose


not to use this interface, instead managing transactions in their
own application code.

Query Object:

Query objects use SQL or Hibernate Query Language (HQL) string to


retrieve data from the database and create objects.

A Query instance is used to bind query parameters, limit the number


of results returned by the query, and finally to execute the query.

Hibernate
Criteria Object:

Criteria object are used to create and execute object oriented criteria
queries to retrieve objects.

Hibernate Properties:
To configure for a databases in a standalone situation
Properties

Description

hibernate.dialect

This property makes Hibernate


generate the appropriate SQL for
the chosen database.

hibernate.connection.driver_class

The JDBC driver class.

hibernate.connection.url

The JDBC URL to the database


instance.

hibernate.connection.username

The database username.

hibernate.connection.password

The database password.

hibernate.connection.pool_size

Limits the number of connections


waiting in the Hibernate database
connection pool.

hibernate.connection.autocommit

Allows autocommit mode to be used


for the JDBC connection.

The database along with an application server and JNDI then you would
have to configure the following properties

Properties

Description

hibernate.connection.datasource

The JNDI name defined in the


application server context you are
using for the application

hibernate.jndi.class

The InitialContext class for JNDI.

hibernate.jndi.<JNDIpropertyname>

Passes any JNDI property you like


to the JNDI InitialContext

hibernate.jndi.url

Provides the URL for JNDI

hibernate.connection.username

The database username.

hibernate.connection.password

The database password.

Example 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>

Hibernate
<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

Hibernate Sessions :

A Session is used to get a physical connection with a database.


The Session object is lightweight and designed to be instantiated
each time an interaction is needed with the database.
Persistent objects are saved and retrieved through a Session object.
The session objects should not be kept open for a long time because
they are not usually thread safe and they should be created and destroyed them
as needed.
The main function of the Session is to offer create, read and delete
operations for instances of mapped entity classes.
Instances/Objects(Persistence Class Object) may exist in one of the following three
states
Transient
Persistent
Detached

Transient State :

When it is just created and has no primary key, the state is called
transient.
If Object is transient, instance has just been instantiated with

Hibernate

new Operator and it's not associated with Hibernate Session.


Transient object will be garbage collected if application doesn't
have any reference any more.
Use the Hibernate session to make an Object persistent.

Example,
Car car = new Car();
car.setName(BMW);
Persistent State :

When the session is opened and the object is just saved in or retrieved from the
database. This state is called persistent.

During this state Hibernate manages the object and saves your
changes, if you commit them.

Below you can see an example. A car is saved and the name is
changed afterwards. As the car is in persistent state, the new name
will be saved.

Session session = HibernateSessionFactory.currentSession();


tx = session.beginTransaction();
session.save(car);
car.setName(Peugeot);
tx.commit();
A persistence instance has a representation in database and an identifier
value. It might have been just saved or loaded. It will be associated
with a hibernate session.
Object States Life Cycle :

Detached State :

When the session was closed, the state changes to detached. The object
is detached from its session.

A detached instance is persistence but its session is closed. It


will be modified in the current state if the reference of the
object is valid.

A detached instance can be reattached to a new session ie it


persistent again.

A Session instance is serializable if its persistent classes are serializable.

A typical transaction should use the following idiom:

Hibernate
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// do some work
...
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
If the Session throws an exception, the transaction must be rolled back
and the session must be discarded.

Hibernate Persistent Class :

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.

POJO Hibernate Rules :

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 getXXX and setXXX methods defined in the JavaBean style.

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

Sample POJO,
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;

Default constructor, Id
& private declaration,

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

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;
}

Hibernate Mapping Files :

An 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.

A number of tools exist to generate the mapping document.


XDoclet,

Middlegen
AndroMDA.
Example,
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;

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;
}

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.

Root
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">

Java class name

<hibernate-mapping>
DB table name
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
Automatic
</meta>
Table primary key
Primary
<id name="id" type="int" column="id">
Key
<generator class="native"/>
generator
Table column
</id>

Java datatype
Converts to
SQL datatype

Hibernate
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
Pojo
<property name="salary" column="salary" type="int"/>
property
</class>
</hibernate-mapping>
Hibernate type
You should save
<classname>.hbm.xml.

the

mapping

document

in

file

with

the

format

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
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
automatically generate the primary key values. Set 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.
When you prepare a Hibernate mapping document, we have seen that
you map 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.

The important methods of Session Interfaces are,


Session org.hibernate.Session

Hibernate

save()
persist()
saveOrUpdate()
merge()
delete()
get()
load()
update()
lock()
replicate()

Transient instances may be made persistent by calling save(), persist() or


saveOrUpdate()

Persistent instances may be made transient by calling delete()

Any instance returned by a get() or load() method is persistent

Detached instances may be made


saveOrUpdate(), lock() or replicate()

The state of a transient or detached instance may also


persistent as a new persistent instance by calling merge().

persistent

by

calling

update(),

be

made

Sample Hibernate CRUD Application :


import java.util.List;
import java.util.Date;
import java.util.Iterator;
import
import
import
import
import

org.hibernate.HibernateException;
org.hibernate.Session;
org.hibernate.Transaction;
org.hibernate.SessionFactory;
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);

Hibernate
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(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();
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();
}
}

Hibernate
/* 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) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}

Important Hibernate Mappings :


Collections 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.SortedMap, java.util.SortedSet, java.util.List,
and
any
array
of
persistent entities or values.

Collection type

Mapping and Description

java.util.Set

This is mapped with a <set> element and


initialized with java.util.HashSet

Hibernate

java.util.SortedSet

This is mapped with a <set> element and


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

java.util.List

This is mapped with a <list> element and


initialized with java.util.ArrayList

java.util.Collection

This is mapped with a <bag> or <ibag> element and


initialized with java.util.ArrayList

java.util.Map

This is mapped with a <map> element and


initialized with java.util.HashMap

java.util.SortedMap

This is mapped with a <map> element and


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

Association Mappings:

The mapping of associations between entity


relationships between tables is the soul of ORM.

An association mapping can be unidirectional as well as bidirectional.

classes

and

the

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

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 it's own life cycle and completely
depends on the life cycle of the owning entity class, then the referred class
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.

Mapping type

Description

Component Mappings

Mapping for a class having a reference to another


class as a member variable.

Hibernate
Hibernate Using Set in Mapping Files : (java.util.Set)

A Set is a java collection that does not contain any duplicate


element.

A Set is mapped with a <set> element in the mapping table and


initialized with java.util.HashSet.

It does not require index element not index based contains only
unique values

You can use Set collection in your class when there is no duplicate
element required in the collection.

Example,
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 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
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;
}
getter ...
setter ...

public class Certificate {


private int id;
private String name;

Hibernate
public Certificate() {}
public Certificate(String name) {
this.name = name;
}
getter ...
setter ...
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;
}
public int hashCode() {
int tmp = 0;
tmp = ( id + name ).hashCode();
return tmp;
}
}

Mapping .hbm 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>
Set mapping definitions
<id name="id" type="int" column="id">
<generator class="native"/>
</id>

element tag is used


If stores string values in
Collection instead of
Entity reference
Inside <set>

Hibernate
<set name="certificates" cascade="all" table=certiticate>
<key column="employee_id"/>
<one-to-many class="Certificate"/>
<element column=answer type=string></element>
</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>

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 ie. table EMPLOYEE.

The <one-to-many> element indicates that one Employee object relates


to many Certificate objects.

You can use either <one-to-one>, <many-to-one> or <many-to-many>


elements based on your requirement.

Using SortedSet (java.util.SortedSet) :

A SortedSet is a java collection that does not contain any duplicate


element and elements 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.

Hibernate

If we use natural ordering then its iterator will traverse the set in
ascending element order.

Example,
Same Table Employee and Certificate which has been used the above
scenario.
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;
}
getters ...
setters ...

The following class 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;
private String name;
public Certificate() {}
public Certificate(String name) {
this.name = name;
}
getters
...
setters
...
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;

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

<?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>
Sorting process
<id name="id" type="int" column="id">
Sort = natural or
<generator class="native"/>
Sort = userdefined class
</id>
<set name="certificates" cascade="all" sort="MyClass" table=employee>
<key column="employee_id"/>
relationships
Foreign key
<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>
The sort attribute can be set to natural to have natural sorting or it can
be set to a custom class implementing java.util.Comparator.
We have used a class MyClass which implements java.util.Comparator to reverse
the sorting order implemented in Certificate class.
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.

Hibernate
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;
}
}}
Using List :

A List is a java collection that stores elements in sequence and allow


duplicate elements and multiple null elements.

The user can access elements by their integer index, and search for
elements in the list.

Its an index based and contains index column

A List is mapped with a <list> element in the mapping table and


initialized with java.util.ArrayList.

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;

Hibernate
this.salary = salary;
}
getters and setters ...
}
<?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">
One-to-many tag is used
<meta attribute="class-description">
Inside <list> to store
This class contains the employee detail.
</meta>
Entity reference in list
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
element tag is used
<list name="certificates" cascade="all" table=employee>
If stores string values in
<key
column="employee_id"/>
Collection instead of
Index of the element
<list-index column="idx"/>
Entity reference
Inside <list>
<one-to-many class="Certificate"/>
<element column=answer type=string></element>
</list>
<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>

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.

Using Collection (java.util.Collection) :

A Bag is a java collection that stores elements without caring about the
sequencing but allow duplicate elements in the list.

Hibernate

A bag is a random grouping of the objects in the list.

Its not index based and does not contain any index column

A Collection is mapped with a <bag> element in the mapping table and


initialized with java.util.ArrayList.

Example,
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) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
getters and setters ...

<?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>
One-to-many tag is used
<id name="id" type="int" column="id">
Inside <bag>
<generator class="native"/>
</id>
<bag name="certificates" cascade="all" table=employee>
<key column="employee_id"/>
element tag is used
<one-to-many class="Certificate"/>
If stores string values in
<element column=answer type=string></element>
Collection instead of
</bag>
Entity reference
<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"/>

Hibernate
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>

The <bag> element is used to


Certificate and Employee classes

set

the

relationship

between

Using Map (java.util.Map) :

A Map is a java collection that stores elements in key-value pairs and


does not allow duplicate elements in the list.

Its an index based collection

The Map interface provides three collection views, which allow a


map's contents to be viewed as a
collection of values, or
set of Keys
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.

Example,
import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
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;
}
getters and setters ...

<?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">

Hibernate
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
Key part in Map
</id>
element tag is used
<map name="certificates" cascade="all" table=employee>
If stores string values in
<key column="employee_id"/>
One-to-many tag is
Collection instead of
<index
column="certificate_type"
type="string"/>
Used Inside <map>
Entity reference here
<one-to-many class="Certificate"/>
Is <element> is value
part
<element column=answer type=string></element>
</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>
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.
Using SortedMap (java.util.SortedMap):

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 Comparator
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.

import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
private SortedMap certificates;

Hibernate
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
setters and getters ...
}
<?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>
Same sort concepts
<id name="id" type="int" column="id">
Used in above
<generator class="native"/>
SortedSet Scenario
</id>
<map name="certificates" cascade="all" sort="MyClass" table=employee>
<key column="employee_id"/>
<index column="certificate_type" type="string"/>
<one-to-many class="Certificate"/>
One-to-many tag is used
Inside <map>
</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>
One-to-many Examples with Collection Mappings

Hibernate

Table Creation
CREATE TABLE `department` (
`department_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`dept_name` VARCHAR(50) NOT NULL DEFAULT '0',
PRIMARY KEY (`department_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=115
CREATE TABLE `employee` (
`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
`birth_date` DATE NULL DEFAULT NULL,
`cell_phone` VARCHAR(15) NULL DEFAULT NULL,
`department_id` BIGINT(20) NULL DEFAULT NULL,
PRIMARY KEY (`employee_id`),
INDEX `FK_DEPT` (`department_id`),
CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES
`department` (`department_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT

Model Class Persistent Class


Department :
public class Department {
private Long departmentId;
private String departmentName;

Hibernate
private Set<Employee> employees;
// Getter and Setter methods
}

Employee :
public class Employee {
private Long employeeId;
private String firstname;
private String lastname;
private Date birthDate;
private String cellphone;
private Department department;
public Employee() {
}
public Employee(String firstname, String lastname, Date birthdate,
String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = birthdate;
this.cellphone = phone;
}
// Getter and Setter methods
}

Hibernate Utill
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

Hibernate
public class HibernateUtil {
private static final SessionFactory sessionFactory =
buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Employee hbm file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Employee" table="EMPLOYEE">
<id name="employeeId" column="EMPLOYEE_ID">
<generator class="native" />
</id>
<property name="firstname" />
<property name="lastname" column="lastname" />
<property name="birthDate" type="date" column="birth_date" />
<property name="cellphone" column="cell_phone" />
<many-to-one name="department"
class="net.viralpatel.hibernate.Department" fetch="select">

Hibernate
<column name="department_id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
Department hbm file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Department" table="DEPARTMENT">
<id name="departmentId" type="java.lang.Long"
column="DEPARTMENT_ID" >
<generator class="native" />
</id>
<property name="departmentName" column="DEPT_NAME"/>
<set name="employees" table="employee"
inverse="true" lazy="true" fetch="select">
<key>
<column name="department_id" not-null="true" />
</key>
<one-to-many class="net.viralpatel.hibernate.Employee" />
</set>
</class>
</hibernate-mapping>
Execute <set> example
import org.hibernate.Session;
import org.hibernate.SessionFactory;
public class Main {

Hibernate
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Department department = new Department();
department.setDepartmentName("Sales");
session.save(department);
Employee emp1 = new Employee("Nina", "Mayers", "1212");
Employee emp2 = new Employee("Tony", "Almeida", "4343");
emp1.setDepartment(department);
emp2.setDepartment(department);
session.save(emp1);
session.save(emp2);
session.getTransaction().commit();
session.close();
}
}
Output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date,
cell_phone, department_id) values (?, ?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date,
cell_phone, department_id) values (?, ?, ?, ?, ?)
One-to-Many <bag> example
A <bag> is an unordered collection, which can contain duplicated elements. That means if you persist a bag
with some order of elements, you cannot expect the same order retains when the collection is retrieved.
There is not a bag concept in Java collections framework, so we just use a java.util.List
correspond to a <bag>.
To implement Bag in our one-to-many mapping example, we will do following changes:
Department

Hibernate
import java.util.ArrayList;
import java.util.List;
public class Department {
private Long departmentId;
private String departmentName;
private List<Employee> employees;
// Getter and Setter methods
}
Department hbm file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Department" table="DEPARTMENT">
<id name="departmentId" type="java.lang.Long"
column="DEPARTMENT_ID" >
<generator class="native" />
</id>
<property name="departmentName" column="DEPT_NAME"/>
<bag name="employees" table="employee"
inverse="true" lazy="true" fetch="select">
<key>
<column name="employee_id" not-null="true" />
</key>
<one-to-many class="net.viralpatel.hibernate.Employee" />
</bag>

Hibernate
</class>
</hibernate-mapping>
output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date,
cell_phone, department_id) values (?, ?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date,
cell_phone, department_id) values (?, ?, ?, ?, ?)
One-to-Many <list> example
A <list> is an indexed collection where the index will also be persisted. That means we can retain the order
of the list when it is retrieved. It differs from <bag> for it persists the element Index while a <bag> does not.
The corresponding type of a <list> in Java is java.util.List.
To implement List in our one-to-many mapping example, we will do following changes:
8.1 Add Index Column in Employee Table
DROP TABLE if exists `employee`;
CREATE TABLE `employee` (
`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
`birth_date` DATE NULL DEFAULT NULL,
`cell_phone` VARCHAR(15) NULL DEFAULT NULL,
`department_id` BIGINT(20) NULL DEFAULT NULL,
`idx` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`employee_id`),
INDEX `FK_DEPT` (`department_id`),
CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES `department`
(`department_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
Department
import java.util.List;
public class Department {
private Long departmentId;

Hibernate
private String departmentName;
private List<Employee> employees;
// Getter and Setter methods
}
Department hbm file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Department" table="DEPARTMENT">
<id name="departmentId" type="java.lang.Long" column="DEPARTMENT_ID">
<generator class="native" />
</id>
<property name="departmentName" column="DEPT_NAME"/>
<list name="employees" table="employee" inverse="false" cascade="all">
<key column="department_id" />
<list-index column="idx" />
<one-to-many class="net.viralpatel.hibernate.Employee" />
</list>
</class>
</hibernate-mapping>
output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?
Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?

Hibernate

One-to-Many <array> example


An <array> has the same usage as a <list> except that it corresponds to an Array type in Java and not a
java.util.List. It is rarely used unless we are mapping for legacy applications. In most cases, we should use
<list> instead. That is because the size of an array cannot be increased or decreased dynamically, where as a
list can.
To implement Array in our one-to-many mapping example, we will do following changes:
public class Department {
private Long departmentId;
private String departmentName;
private Employee[] employees;
// Getter and Setter methods
}
We simply change the List of Employees to Array of Employee [].
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Department" table="DEPARTMENT">
<id name="departmentId" type="java.lang.Long" column="DEPARTMENT_ID">
<generator class="native" />
</id>

Hibernate
<property name="departmentName" column="DEPT_NAME"/>
<array name="employees" table="employee" inverse="false" cascade="all">
<key column="department_id" />
<list-index column="idx" />
<one-to-many class="net.viralpatel.hibernate.Employee" />
</array>
</class>
</hibernate-mapping>
Output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?
Hibernate: update EMPLOYEE set department_id=?, idx=? where EMPLOYEE_ID=?

Association :
Many-to-One :
<?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>

Seperate tag
Is used here

Hibernate
<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>

Many-to-One
Relationships

<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>
The <many-to-one> element is used to set the relationship between EMPLOYEE
and ADDRESS entities. Multiple EMPLOYEE'S can contain the same ADDRESS
here
One-to-One :

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.

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.

<?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"/>
One-to-one
</id>
Relationship
<property name="firstName" column="first_name" type="string"/> Seperate tag
But used
<property name="lastName" column="last_name" type="string"/>
Is used here
Many-to-one
<property name="salary" column="salary" type="int"/>
element
<many-to-one name="address" column="address" unique="true" class="Address"
not-null="true"/>

Hibernate
</class>

Set unique
Constraint to make
The one-to-one mapping

<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>

The <many-to-one> element is used to set the relationship between


EMPLOYEE and ADDRESS entities. The column attribute which is set to
unique so that only one Employee object can be associated with an
address object.

We can use <one-to-one> in both persistent class for mapping


one-to-one relationship. This is another way to implement.

<?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"/>
One-to-one
<property name="salary" column="salary" type="int"/>
Relationship
<one-to-one name=address cascade=all/>
</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"/>

Hibernate
One-to-one
Relationship

<property name="state" column="state_name" type="string"/>


<property name="zipcode" column="zipcode" type="string"/>
<one-to-one name=employee/>
</class>

</hibernate-mapping>
One-to-Many :
A One-to-Many mapping can be implemented using a Set java collection
<?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" table=employee>
<key column="employee_id"/>
One-to-many tag is used
Inside <set>
<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>
Many-to-Many :
A Many-to-Many mapping can be implemented using a Set java collection
<?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
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
Table is used
<id name="id" type="int" column="id">
To display
<generator class="native"/>
All records
</id>
<set name="certificates" cascade="save-update" table="EMP_CERT"> Many-to-many tag
<key column="employee_id"/>
Is used inside
<set>
<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">
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>

Hibernate One To One Mapping Tutorial (XML Mapping)


Example,
/* EMPLOYEE table */
CREATE TABLE `employee` (
`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
`birth_date` DATE NOT NULL,
`cell_phone` VARCHAR(15) NOT NULL,
PRIMARY KEY (`employee_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=216

/* EMPLOYEEDETAIL table */
CREATE TABLE `employeedetail` (
`employee_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`street` VARCHAR(50) NULL DEFAULT NULL,
`city` VARCHAR(50) NULL DEFAULT NULL,
`state` VARCHAR(50) NULL DEFAULT NULL,

Hibernate
`country` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`employee_id`),
CONSTRAINT `FKEMPL` FOREIGN KEY (`employee_id`) REFERENCES `employee`
(`employee_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=216
public class Employee {
private
private
private
private
private
private

Long employeeId;
String firstname;
String lastname;
Date birthDate;
String cellphone;
EmployeeDetail employeeDetail;

public Employee() {
}
public Employee(String firstname, String lastname, Date birthdate,
String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = birthdate;
this.cellphone = phone;
}

// Getter and Setter methods

public class EmployeeDetail {


private
private
private
private
private

Long employeeId;
String street;
String city;
String state;
String country;

private Employee employee;


public EmployeeDetail() {
}
public EmployeeDetail(String street, String city, String state, String
country) {
this.street = street;
this.city = city;
this.state = state;
this.country = country;
}

Hibernate
// Getter and Setter methods
}

Note that in above model classes, employeeId is common. This is the primary key of Employee table
that exhibits One-to-one relationship with EmployeeDetail table.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Employee" table="EMPLOYEE">
<id name="employeeId" column="EMPLOYEE_ID">
<generator class="native" />
</id>
<one-to-one name="employeeDetail"
class="net.viralpatel.hibernate.EmployeeDetail"
cascade="save-update"></one-to-one>
<property
<property
<property
<property

name="firstname" />
name="lastname" column="lastname" />
name="birthDate" type="date" column="birth_date" />
name="cellphone" column="cell_phone" />

</class>
<class name="EmployeeDetail" table="EMPLOYEEDETAIL">
<id name="employeeId" type="java.lang.Long">
<column name="EMPLOYEE_ID" />
<generator class="foreign">
<param name="property">employee</param>
</generator>
</id>
<one-to-one name="employee" class="net.viralpatel.hibernate.Employee"
constrained="true"></one-to-one>
<property
<property
<property
<property
</class>

name="street" column="STREET"/>
name="city" column="CITY"/>
name="state" column="STATE"/>
name="country" column="COUNTRY"/>

</hibernate-mapping>

Note that in above hibernate mapping we are implementing One-to-one


relationship. For both the model classes we are using a single primary key
EmployeeId. In EmployeeDetail hbm file we have defined a foreign identifier
generator so that primary it uses primary key of Employee table.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

Hibernate
<hibernate-configuration>
<session-factory>
<property
name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property
name="connection.url">jdbc:mysql://localhost:3306/tutorial</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">validate</property>
<mapping resource="net/viralpatel/hibernate/EmployeeDetail.hbm.xml"/>
<mapping resource="net/viralpatel/hibernate/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();

ex);

private static SessionFactory buildSessionFactory() {


try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration()
.configure()
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." +
}

throw new ExceptionInInitializerError(ex);

}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
public class Main {
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();

Hibernate
EmployeeDetail employeeDetail = new EmployeeDetail("10th Street",
"LA", "San Francisco", "U.S.");
Employee employee = new Employee("Nina", "Mayers", new Date(121212),
"114-857-965");
employee.setEmployeeDetail(employeeDetail);
employeeDetail.setEmployee(employee);

session.save(employee);

List<Employee> employees = session.createQuery("from


Employee").list();
for (Employee employee1 : employees) {
System.out.println(employee1.getFirstname() + " , "
+ employee1.getLastname() + ", "
+ employee1.getEmployeeDetail().getState());
}
session.getTransaction().commit();
session.close();

Output
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone)
values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEEDETAIL (STREET, CITY, STATE, COUNTRY,
EMPLOYEE_ID) values (?, ?, ?, ?, ?)
Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_1_, employee0_.firstname
as firstname1_, employee0_.lastname as lastname1_, employee0_.birth_date as
birth4_1_, employee0_.cell_phone as cell5_1_ from EMPLOYEE employee0_
Hibernate: select employeede0_.EMPLOYEE_ID as EMPLOYEE1_0_0_,
employeede0_.STREET as STREET0_0_, employeede0_.CITY as CITY0_0_,
employeede0_.STATE as STATE0_0_, employeede0_.COUNTRY as COUNTRY0_0_ from
EMPLOYEEDETAIL employeede0_ where employeede0_.EMPLOYEE_ID=?
Nina , Mayers, San Francisco

Hibernate One To One Annotation Mapping Tutorial


import java.sql.Date;
import
import
import
import
import
import
import

javax.persistence.CascadeType;
javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.Id;
javax.persistence.OneToOne;
javax.persistence.Table;

Hibernate
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue
@Column(name="employee_id")
private Long employeeId;
@Column(name="firstname")
private String firstname;
@Column(name="lastname")
private String lastname;
@Column(name="birth_date")
private Date birthDate;
@Column(name="cell_phone")
private String cellphone;
@OneToOne(mappedBy="employee", cascade=CascadeType.ALL)
private EmployeeDetail employeeDetail;
public Employee() {
}
public Employee(String firstname, String lastname, Date birthdate, String
phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = birthdate;
this.cellphone = phone;
}

// Getter and Setter methods

import
import
import
import
import
import
import

javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.Id;
javax.persistence.OneToOne;
javax.persistence.PrimaryKeyJoinColumn;
javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@Entity
@Table(name="EMPLOYEEDETAIL")
public class EmployeeDetail {
@Id

Hibernate
@Column(name="employee_id", unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",
parameters=@Parameter(name="property", value="employee"))
private Long employeeId;
@Column(name="street")
private String street;
@Column(name="city")
private String city;
@Column(name="state")
private String state;
@Column(name="country")
private String country;
@OneToOne
@PrimaryKeyJoinColumn
private Employee employee;
public EmployeeDetail() {
}
public EmployeeDetail(String street, String city, String state, String
country) {
this.street = street;
this.city = city;
this.state = state;
this.country = country;
}
// Getter and Setter methods
}

Note that in EmployeeDetail class we have used @GenericGenerator to specify primary key. This
will ensure that the primary key from Employee table is used instead of generating a new one.
Hibernate-configuration file
Instead of <mapping resource = hbm file location> using the following tag rest of all same as above
<mapping class="net.viralpatel.hibernate.EmployeeDetail"/>
<mapping class="net.viralpatel.hibernate.Employee"/>

Hibernate Utill
Instead of Configuration here using the AnnotationConfiguration class to create configuration object
return new AnnotationConfiguration().configure().buildSessionFactory();

Many-to-one Mapping using Annotation :

Hibernate

@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue
@Column(name="employee_id")
private Long employeeId;
@Column(name="firstname")
private String firstname;
@Column(name="lastname")
private String lastname;
@Column(name="birth_date")
private Date birthDate;
@Column(name="cell_phone")
private String cellphone;
@ManyToOne
@JoinColumn(name="department_id")
private Department department;
public Employee() {
}
public Employee(String firstname, String lastname, String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = new Date(System.currentTimeMillis());
this.cellphone = phone;
}

// Getter and Setter methods

@Entity
@Table(name="DEPARTMENT")
public class Department {
@Id

Hibernate
@GeneratedValue
@Column(name="DEPARTMENT_ID")
private Long departmentId;
@Column(name="DEPT_NAME")
private String departmentName;
@OneToMany(mappedBy="department")
private Set<Employee> employees;

Accept only unique values

// Getter and Setter methods


}

mappedBy refers to the property name of the association on the owner side. In our case, this is
passport. As you can see, you dont have to (must not) declare the join column since it has already
been declared on the owners side.
Implemented Class
public class Main {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Department department = new Department();
department.setDepartmentName("Sales");
session.save(department);
Employee emp1 = new Employee("Nina", "Mayers", "111");
Employee emp2 = new Employee("Tony", "Almeida", "222");
emp1.setDepartment(department);
emp2.setDepartment(department);
session.save(emp1);
session.save(emp2);

session.getTransaction().commit();
session.close();

Output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone,
department_id) values (?, ?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone,
department_id) values (?, ?, ?, ?, ?)

Hibernate
One- To Many Bi-directional Indexed mapping
CREATE TABLE `employee` (
`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
`birth_date` DATE NULL DEFAULT NULL,
`cell_phone` VARCHAR(15) NULL DEFAULT NULL,
`department_id` BIGINT(20) NULL DEFAULT NULL,
`idx` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`employee_id`),
INDEX `FK_DEPT` (`department_id`),
CONSTRAINT `FK_DEPT` FOREIGN KEY (`department_id`) REFERENCES `department`
(`department_id`)
)
@Entity
@Table(name="DEPARTMENT")
public class Department {
@Id
@GeneratedValue
@Column(name="DEPARTMENT_ID")
private Long departmentId;
@Column(name="DEPT_NAME")
private String departmentName;
@OneToMany(cascade={CascadeType.ALL})
@JoinColumn(name="department_id")
@IndexColumn(name="idx")
private List<Employee> employees;
// Getter and Setter methods
}

Note that in Department entity class, we removed mappedBy clause from @OneToMany. This mark
Department as the relationship owner and make it responsible to update foreign keys and index values.
Also we specified index column using @IndexColumn annotation to specify which column in Employee table
we would like to store index in.

@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue
@Column(name="employee_id")
private Long employeeId;
@Column(name="firstname")

Hibernate
private String firstname;
@Column(name="lastname")
private String lastname;
@Column(name="birth_date")
private Date birthDate;
@Column(name="cell_phone")
private String cellphone;
@ManyToOne
@JoinColumn(name="department_id",
Foreign Key
insertable=false, updatable=false,
nullable=false)
private Department department;
public Employee() {
}
public Employee(String firstname, String lastname, String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = new Date(System.currentTimeMillis());
this.cellphone = phone;
}

// Getter and Setter methods

public class Main {


@SuppressWarnings("unchecked")
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Department department = new Department();
department.setDepartmentName("Sales");
Employee emp1 = new Employee("Nina", "Mayers", "111");
Employee emp2 = new Employee("Tony", "Almeida", "222");
department.setEmployees(new ArrayList<Employee>());
department.getEmployees().add(emp1);
department.getEmployees().add(emp2);
session.save(department);
session.getTransaction().commit();
session.close();
}

Hibernate
Output
Hibernate: insert into DEPARTMENT (DEPT_NAME) values (?)
Hibernate: insert into EMPLOYEE (birth_date, cell_phone, firstname, lastname)
values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEE (birth_date, cell_phone, firstname, lastname)
values (?, ?, ?, ?)
Hibernate: update EMPLOYEE set department_id=?, idx=? where employee_id=?
Hibernate: update EMPLOYEE set department_id=?, idx=? where employee_id=?

Many-to-many

CREATE TABLE `employee` (


`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`employee_id`)
)

CREATE TABLE `meeting` (


`meeting_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`subject` VARCHAR(50) NOT NULL,
`meeting_date` DATE NOT NULL,
PRIMARY KEY (`meeting_id`)
)

CREATE TABLE `employee_meeting` (


`employee_id` BIGINT(20) NOT NULL,
`meeting_id` BIGINT(20) NOT NULL,
PRIMARY KEY (`employee_id`, `meeting_id`),
INDEX `FK_MEETING` (`meeting_id`),

Hibernate
CONSTRAINT `FK_EMPLOYEE` FOREIGN KEY (`employee_id`) REFERENCES `employee`
(`employee_id`),
CONSTRAINT `FK_MEETING` FOREIGN KEY (`meeting_id`) REFERENCES `meeting`
(`meeting_id`)
)
public class Employee {
private Long employeeId;
private String firstname;
private String lastname;
private Set<Meeting> meetings = new HashSet<Meeting>();
public Employee() {
}
public Employee(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}

// Getter and Setter methods

public class Meeting {


private Long meetingId;
private String subject;
private Date meetingDate;
private Set<Employee> employees = new HashSet<Employee>();
public Meeting(String subject) {
this.subject = subject;
this.meetingDate = new Date();
}
// Getter and Setter methods
}
<hibernate-mapping package="net.viralpatel.hibernate">
<class name="Employee" table="EMPLOYEE">
<id name="employeeId" column="EMPLOYEE_ID">
<generator class="native" />
</id>
<property name="firstname" />
<property name="lastname" column="lastname" />
<set name="meetings" table="EMPLOYEE_MEETING"
inverse="false" lazy="true" fetch="select" cascade="all">
<key column="EMPLOYEE_ID" />

Hibernate
<many-to-many column="MEETING_ID" class="Meeting" />
</set>
</class>
<class name="Meeting" table="MEETING">
<id name="meetingId" type="java.lang.Long"
column="MEETING_ID">
<generator class="native" />
</id>
<property name="subject" column="SUBJECT" />
<property name="meetingDate" type="date" column="MEETING_DATE" />
<set name="employees" table="EMPLOYEE_MEETING"
inverse="true" lazy="true" fetch="select">
<key column="EMPLOYEE_ID" />
<many-to-many column="MEETING_ID" class="Meeting" />
</set>
</class>
</hibernate-mapping>

One thing is worth noting here is that we have mentioned keyword inverse=true in Meeting class
which makes Employee as relationship owner. Thus Employee model takes care of updating
referential keys in dependent models
public class Main {
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();

Meeting meeting1 = new Meeting("Quaterly Sales meeting");


Meeting meeting2 = new Meeting("Weekly Status meeting");
Employee employee1 = new Employee("Sergey", "Brin");
Employee employee2 = new Employee("Larry", "Page");
employee1.getMeetings().add(meeting1);
employee1.getMeetings().add(meeting2);
employee2.getMeetings().add(meeting1);
session.save(employee1);
session.save(employee2);

}
}

session.getTransaction().commit();
session.close();

Hibernate
Output
Hibernate:
Hibernate:
Hibernate:
Hibernate:
Hibernate:
Hibernate:
Hibernate:

insert
insert
insert
insert
insert
insert
insert

into
into
into
into
into
into
into

EMPLOYEE (firstname, lastname) values (?, ?)


MEETING (SUBJECT, MEETING_DATE) values (?, ?)
MEETING (SUBJECT, MEETING_DATE) values (?, ?)
EMPLOYEE (firstname, lastname) values (?, ?)
EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)
EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)
EMPLOYEE_MEETING (EMPLOYEE_ID, MEETING_ID) values (?, ?)

Many-to-many Annotation
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@Column(name="EMPLOYEE_ID")
@GeneratedValue
private Long employeeId;
@Column(name="FIRSTNAME")
private String firstname;
@Column(name="LASTNAME")
private String lastname;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="EMPLOYEE_MEETING",
joinColumns={@JoinColumn(name="EMPLOYEE_ID")},
inverseJoinColumns={@JoinColumn(name="MEETING_ID")})
private Set<Meeting> meetings = new HashSet<Meeting>();
public Employee() {
}
public Employee(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
// Getter and Setter methods
}

Hibernate
@Entity
@Table(name="MEETING")
public class Meeting {
@Id
@Column(name="MEETING_ID")
@GeneratedValue
private Long meetingId;
@Column(name="SUBJECT")
private String subject;
@Column(name="MEETING_DATE")
private Date meetingDate;
@ManyToMany(mappedBy="meetings")
private Set<Employee> employees = new HashSet<Employee>();
public Meeting(String subject) {
this.subject = subject;
this.meetingDate = new Date();
}
// Getter and Setter methods
}

@ManyToMany Is used to create many-to-many relationship between Employee and Meeting


entities.
Employee is defined as relationship owner as @JoinColumn is define in Employee class and
mappedBy is specified in Meeting class
@JoinTable Is used to define the join table (link table) for many-to-many relationship
@JoinColumn Is used to define the join column (linking column) in both main tables.

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.

import java.util.*;
public class Employee implements java.io.Serializable {
private int id;
private String firstName;
private String lastName;
private int salary;

Hibernate
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;
}
getters and setters ...
}
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;
}
getters and setters ...
}

<?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>
Mention Address class
<id name="id" type="int" column="id">
Attributes Inside <component>
<generator class="native"/>
tag
</id>
<component name="address" class="Address">

Hibernate
<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>
</hibernate-mapping>
The <component> element sets the existence of different attributes of
Address class inside Employee classes.
public class App {
public static void main(String[] args) {
System.out.println("Hibernate component mapping");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Address address = new Address();
address.setStreet("Street");
address.setCity("City");
address.setState("State");
address.setZipCode("ZipcOde");
Customer cust = new Customer();
cust.setCustName("mkyong");
cust.setAge(30);
cust.setAddress(address);
cust.setCreatedDate(new Date());
cust.setCreatedBy("system");
session.save(cust);
session.getTransaction().commit();
System.out.println("Done");
}

INSERT
INTO
mkyongdb.customer
(STREET, CITY, STATE, ZIPCODE, FIRSTNAME, LASTNAME, SALARY)

Hibernate
VALUES
(?, ?, ?, ?, ?, ?, ?)

Hibernate Annotations :
Hibernate Annotations is the powerful way to provide the meta-data for
the Object and Relational Table mapping.
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() {}
getters and setters ...
}

@Entity :

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 :

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


override 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.

Hibernate
@Id and @GeneratedValue :

Each entity bean will have a primary key, which 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.

@Column :
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.

Hibernate Query Language (HQL):

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.

It doesn't depend on the table of the database, instead of table name we use class
name.

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 strategies.

Keywords like SELECT , FROM and WHERE etc. are not case sensitive but
properties like table and column names are case sensitive in HQL.

Hibernate

The main difference between is HQL uses class name instead of table name, and property
names instead of column name.

Advantages :

Database independent

supports polymorphic queries

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:

Fully qualified class name

String hql = "FROM com.hibernatebook.criteria.Employee";


Query query = session.createQuery(hql);
List results = query.list();
String hql = "FROM com.hibernatebook.criteria.Employee Where id=:id";
Query query = session.createQuery(hql);
query.setParameter(id, 123);
List results = query.list();
AS Clause :

The AS clause can be used to assign aliases to the classes in your HQL
queries, specially when you have 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


directly after the class name, as follows:

specify

the

alias

Without AS keyword

String hql = "FROM Employee E";


Query query = session.createQuery(hql);
List results = query.list();

SELECT Clause :

The SELECT clause provides more control over the result set than the

Hibernate
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 specific 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();
Using Parameters
String hql = "FROM Employee E WHERE E.id = :empid";
Query query = session.createQuery(hql);
query.setParameter(empid, 10);
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:

Hibernate
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();

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.firtName 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);
Get user input &
query.setParameter("employee_id",10);
Set to named param
List results = query.list();

UPDATE Clause :

Bulk updates are new to HQL with Hibernate 3, and deletes 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);

Hibernate
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

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

avg(property name)

The average of a property's value

count(property name or *)

The number of times a property occurs


in the results

max(property name)

The maximum value of the property


values

min(property name)

The minimum value of the property


values

sum(property name)

The sum total of the property values

The distinct keyword only counts the unique values in the row set. The following

Hibernate
query will return only unique count:
String hql = "SELECT count(distinct E.firstName) FROM Employee E";
Query query = session.createQuery(hql);
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)


This method takes an integer that represents the first row in
your result set, starting with row 0.

Query setMaxResults(int maxResult)


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(5);
query.setMaxResults(10);
List results = query.list(); // will return records from 5 to 10th number

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.

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();

Hibernate

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 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 in-sensitive form of the above restriction.
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:

Hibernate
org.hibernate.criterion.LogicalExpression LogicalExpression
org.hibernate.criterion.Restrictions Restrictions
Criteria cr = session.createCriteria(Employee.class);
Criterion salary = Restrictions.gt("salary", 2000);
Criterion name = Restrictions.ilike("firstNname","zara%");
// To get records matching with OR conditions
LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );
// To get records matching with AND conditions
LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );
List results = cr.list();

Pagination using Criteria:


There are two methods of the Criteria interface for pagination.
S.N.

Method & Description

public Criteria setFirstResult(int firstResult)


This method takes an integer that represents the first row in
your result set, starting with row 0.

public Criteria setMaxResults(int maxResults)


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);
starting from 1st record
cr.setMaxResults(10); and retrieve the 10 records from db
List results = cr.list();

Sorting the Results :


The Criteria API provides the org.hibernate.criterion.Order 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:

Hibernate
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 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
used 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"));
Example,
Session session = factory.openSession();
Transaction tx = null;
Criteria Creation
try{
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Employee.class);
// Add restriction.

Hibernate
Return results

cr.add(Restrictions.gt("salary", 2000));
List employees = cr.list();

Add Restrictions

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();
}

Why not Criteria !?


The Criteria API do bring some disadvantages.

1. Performance issue
You have no way to control the SQL query generated by Hibernate, if the generated query is slow, you
are very hard to tune the query, and your database administrator may not like it.

2. Maintenance issue
All the SQL queries are scattered through the Java code, when a query went wrong, you may spend
time to find the problem query in your application. On the others hand, named queries stored in the
Hibernate mapping files are much more easier to maintain.

Hibernate Native SQL :


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.

Hibernate
Scalar queries:

The most basic SQL query is to get a list of scalars (values) from one or
more tables.

returning scalar values, basically returning the "raw" values from


the resultset

Following is the syntax for using native SQL for scalar 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();
ALIAS_TO_ENTITY_MAP Each row of results is a Map from alias to
entity instance
DISTINCT_ROOT_ENTITY Each row of results is a distinct instance of
the root entity
FULL_JOIN Specifies joining to an entity based on a full join
INNER_JOIN Specifies joining to an entity based on an inner join
LEFT_JOIN Specifies joining to an entity based on a left outer join
PROJECTION This result transformer is selected implicitly by calling
setProjection()
ROOT_ALIAS The alias that refers to the "root" entity of the criteria
query
ROOT_ENTITY Each row of results is an instance of the root entity
If we have Student in a ManyToMany relationship to Department a query
might look like this ...
Session session = (Session) getEntityManager().getDelegate();
Criteria crit = session.createCriteria(Student.class)
.createAlias('departments', 'department');
This query will return duplicates. But set the ResultTransformer as
crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
Now the results will be distinct when Hibernate marshalls the results
Example,
public void listEmployeesScalar( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();

ResultTransformer

Hibernate
String sql = "SELECT first_name, salary FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List data = query.list();

List of Object which

for(Object object : data)


Converts to Map
{
Map row = (Map)object;
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();
}

Entity queries:

The 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();

Note : All Select (*) data will match to Employee.class properties automatically.
Example,
public void listEmployeesEntity( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
String sql = "SELECT * FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);List of Employee
Objects
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();

Hibernate

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

Named SQL queries:

The 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";


SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
query.setParameter("employee_id", 10);
List results = query.list();

Hibernate Named Query Examples


Often times, developer like to put HQL string literals scatter all over the Java code, this method is hard
to maintain and look ugly. Fortunately, Hibernate come out a technique called names queries , it lets
developer to put all HQL into the XML mapping file or via annotation.
How to declare named query
The named query is supported in both HQL or native SQL. see examples
HQL in mapping file
<!-- stock.hbm.xml -->
<hibernate-mapping>
<class name="com.mkyong.common.Stock" table="stock" ...>
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="identity" />
</id>
<property name="stockCode" type="string">

Hibernate
<column name="STOCK_CODE" length="10" not-null="true" unique="true"
/>
</property>
...
</class>

<query name="findStockByStockCode">
<![CDATA[from Stock s where s.stockCode = :stockCode]]>
</query>

</hibernate-mapping>

Native SQL in mapping file

<!-- stock.hbm.xml -->


<hibernate-mapping>
<class name="com.mkyong.common.Stock" table="stock" ...>
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="identity" />
</id>
<property name="stockCode" type="string">
<column name="STOCK_CODE" length="10" not-null="true" unique="true"

Hibernate
/>
</property>
...
</class>

<sql-query name="findStockByStockCodeNativeSQL">
<return alias="stock" class="com.mkyong.common.Stock"/>
<![CDATA[select * from stock s where s.stock_code = :stockCode]]>
</sql-query>
</hibernate-mapping>

You can place a named query inside hibernate-mapping element, but do not put before the class
element, Hibernate will prompt invalid mapping file, all your named queries have to put after the
class element.
Note
Regarding the CDATA , its always good practice to wrap your query text with CDATA, so that the XML
parser will not prompt error for some special XML characters like > , < and etc.
HQL in annotation
@NamedQueries({
@NamedQuery(
name = "findStockByStockCode",
query = "from Stock s where s.stockCode = :stockCode"
)
})
@Entity

Hibernate
@Table(name = "stock", catalog = "mkyong")
public class Stock implements java.io.Serializable {

Native SQL in annotation


@NamedNativeQueries({
@NamedNativeQuery(
name = "findStockByStockCodeNativeSQL",
query = "select * from stock s where s.stock_code = :stockCode",
resultClass = Stock.class
)
})
@Entity
@Table(name = "stock", catalog = "mkyong")
public class Stock implements java.io.Serializable {

In native SQL, you have to declare the resultClass to let Hibernate know what is the return type,
failed to do it will caused the exception org.hibernate.cfg.NotYetImplementedException: Pure
native scalar queries are not yet supported.

Call a named query


In Hibernate, you can call the named query via getNamedQuery method.
Query query = session.getNamedQuery("findStockByStockCode")
.setString("stockCode", "7277");
Query query = session.getNamedQuery("findStockByStockCodeNativeSQL")
.setString("stockCode", "7277");

Hibernate
How To Call Stored Procedure In Hibernate

MySQL store procedure


DELIMITER $$

CREATE PROCEDURE `GetStocks`(int_stockcode VARCHAR(20))


BEGIN
SELECT * FROM stock WHERE stock_code = int_stockcode;
END $$

DELIMITER ;

In MySQL, you can simple call it with a call keyword :


CALL GetStocks('7277');

Hibernate call store procedure


In Hibernate, there are three approaches to call a database store procedure.

Native SQL createSQLQuery


You can use createSQLQuery() to call a store procedure directly.
Query query = session.createSQLQuery(
"CALL GetStocks(:stockCode)")
.addEntity(Stock.class)
.setParameter("stockCode", "7277");

Hibernate
List result = query.list();
for(int i=0; i<result.size(); i++){
Stock stock = (Stock)result.get(i);
System.out.println(stock.getStockCode());
}

2. NamedNativeQuery in annotation
Declare your store procedure inside the @NamedNativeQueries annotation.
//Stock.java
...
@NamedNativeQueries({
@NamedNativeQuery(
name = "callStockStoreProcedure",
query = "CALL GetStocks(:stockCode)",
resultClass = Stock.class
)
})
@Entity
@Table(name = "stock")
public class Stock implements java.io.Serializable {
...

Call it with getNamedQuery().

Hibernate
Query query = session.getNamedQuery("callStockStoreProcedure")
.setParameter("stockCode", "7277");
List result = query.list();
for(int i=0; i<result.size(); i++){
Stock stock = (Stock)result.get(i);
System.out.println(stock.getStockCode());
}

3. sql-query in XML mapping file


Declare your store procedure inside the sql-query tag.
<!-- Stock.hbm.xml -->
...
<hibernate-mapping>
<class name="com.mkyong.common.Stock" table="stock" ...>
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="identity" />
</id>
<property name="stockCode" type="string">
<column name="STOCK_CODE" length="10" not-null="true" unique="true"
/>
</property>

Hibernate
...
</class>

<sql-query name="callStockStoreProcedure">
<return alias="stock" class="com.mkyong.common.Stock"/>
<![CDATA[CALL GetStocks(:stockCode)]]>
</sql-query>

</hibernate-mapping>

Call it with getNamedQuery().


Query query = session.getNamedQuery("callStockStoreProcedure")
.setParameter("stockCode", "7277");
List result = query.list();
for(int i=0; i<result.size(); i++){
Stock stock = (Stock)result.get(i);
System.out.println(stock.getStockCode());

From JAVA-T-POINT :
Hibernate Framework :

Hibernate framework simplifies the development of JAVA application


to interact with the database.

Hibernate is an open source, lightweight, ORM (Object Relational


Mapping) tool.

An ORM tool simplifies the data creation, data manipulation and

Hibernate
data access.

It is a programming technique that maps the object to the data


stored in the database.

The ORM tool internally uses the JDBC API to interact with the
database.

Advantages of Hibernate Framework :


There are many advantages of Hibernate Framework.
1) Open source and Lightweight : Hibernate framework is open source under the
LGPL license and lightweight.
2) Fast performance : The performance of hibernate framework is fast
because cache is internally used in hibernate framework. There are two
types of cache in hibernate framework first level cache and second level cache.
First level cache is enabled by default.
3) Database Independent query : HQL (Hibernate Query Language) is the
object-oriented version of SQL. It generates the database independent
queries. So you don't need to write database specific queries. Before
Hibernate, If database is changed for the project, we need to change the
SQL query as well that leads to the maintenance problem.
4) Automatic table creation : Hibernate framework provides the facility to
create the tables of the database automatically. So there is no need to
create tables in the database manually.
5) Simplifies complex join : To fetch data from multiple tables is easy in
hibernate framework.
6) Provides query statistics and database status : Hibernate supports Query cache
and provide statistics about query and database status.
Hibernate Architecture :
The Hibernate architecture includes many objects

persistent object,

session factory,

transaction factory,

Hibernate

connection factory,

session,

transaction etc.

There are 4 layers in hibernate architecture

JAVA application layer,

hibernate framework layer,

backhand API layer and

database layer.

This is the high level architecture of Hibernate with mapping file and
configuration file.

Hibernate

Hibernate framework uses many objects session factory, session,


transaction etc. along with existing Java API such as JDBC (Java Database
Connectivity), JTA (Java Transaction API) and JNDI (Java Naming
Directory Interface).
Elements of Hibernate Architecture :
SessionFactory :

The SessionFactory is a factory of session and client of


ConnectionProvider.

It holds second level cache (optional) of data.

The org.hibernate.SessionFactory interface provides factory method to


get the object of Session.

Session :

The session object provides an interface between the application


and data stored in the database.

It is a short-lived object and wraps the JDBC connection.

It is factory of Transaction, Query and Criteria.

It holds a first-level cache (mandatory) of data.

The org.hibernate.Session interface provides methods to insert, update


and delete the object.

Hibernate

It also provides factory methods for Transaction, Query and


Criteria.

Transaction :

The transaction object specifies the atomic unit of work. It is


optional.

The org.hibernate.Transaction interface provides methods for transaction


management.

ConnectionProvider :

It is a factory of JDBC connections.

It abstracts the application from DriverManager or DataSource. It is


optional.

TransactionFactory :

It is a factory of Transaction. It is optional.

Persistent class Rules :

A no-arg constructor: It is recommended that you have a default


constructor at least package visibility so that hibernate can
create the instance of the Persistent class by newInstance() method.

Provide an identifier property (optional): It is mapped to the primary key


column of the database.

Declare getter and setter methods (optional): The Hibernate recognizes the
method by getter and setter method names by default.

Prefer non-final class: Hibernate uses the concept of proxies, that


depends on the persistent class. The application programmer will
not be able to use proxies for lazy association fetching.

Example,
public class Employee {
private int id;
private String firstName,lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;

Hibernate
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

Create the mapping file for Persistent class :


The mapping file name Conventionally, should be class_name.hbm.xml. There
are many elements of the mapping file.

hibernate-mapping is the root element in the mapping file.

class It is the sub-element of the hibernate-mapping element. It


specifies the Persistent class.

id It is the sub-element of class. It specifies the primary key


attribute in the class.

generator It is the sub-element of id. It is used to generate the


primary key. There are many generator classes such as

assigned (It is used if id is specified by the user),

increment,

hilo,

sequence,

native etc.

property It is the sub-element of class that specifies the property


name of the Persistent class.

<?xml version='1.0' encoding='UTF-8'?>


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

Hibernate
<hibernate-mapping>
<class name="com.javatpoint.mypackage.Employee" table="emp1000">
<id name="id">
<generator class="assigned"></generator>
</id>
<property name="firstName"></property>
<property name="lastName"></property>
</class>
</hibernate-mapping>

Create the Configuration file :


The configuration file contains informations about the database and
mapping file.
Conventionally, its name should be hibernate.cfg.xml.
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hbm2ddl.auto">update</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.url">
jdbc:oracle:thin:@localhost:1521:xe</property>
<property name="connection.username">system</property>
<property name="connection.password">oracle</property>
<property name="connection.driver_class">
oracle.jdbc.driver.OracleDriver</property>
<mapping resource="employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
import org.hibernate.Session;
import org.hibernate.SessionFactory;

Hibernate
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class StoreData {
public static void main(String[] args) {
//creating configuration object
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");//populates the data of the
configuration file
//creating seession factory object
SessionFactory factory=cfg.buildSessionFactory();
//creating session object
Session session=factory.openSession();
//creating transaction object
Transaction t=session.beginTransaction();
Employee e1=new Employee();
e1.setId(115);
e1.setFirstName("sonoo");
e1.setLastName("jaiswal");
session.persist(e1);//persisting the object
t.commit();//transaction is commited
session.close();
System.out.println("successfully saved");
}
}
Load the jar file :
For successfully running the hibernate application, you should have the
hibernate4.jar file.
Some other jar files or packages are required such as

cglib

log4j

commons

SLF4J

dom4j

xalan

Hibernate

xerces

Hibernate With Annotation :


There are many annotation to create hibernate Application such as

@Entity

@Table

@Id

@Column etc

Those are all based on the JPA 2 Specification and supports all
features.

All JPA Annotation are defined in the javax.persistence.*


package.

Hibernate EntityManager implements the interfaces and life


cycle defined by the JPA specification.

The core advantage of using hibernate annotation is that you


don't need to create mapping (hbm) file. Here, hibernate
annotations are used to provide meta-data.

Example,
import org.hibernate.*;
import org.hibernate.cfg.*;
public class Test {
public static void main(String[] args) {
Session session = new AnnotationConfiguration()
.configure().buildSessionFactory().openSession();
Transaction t=session.beginTransaction();
Employee e1=new Employee();
e1.setId(1001);
e1.setFirstName("sonoo");
e1.setLastName("jaiswal");
Employee e2=new Employee();
e2.setId(1002);
e2.setFirstName("vimal");

Hibernate
e2.setLastName("jaiswal");
session.persist(e1);
session.persist(e2);
t.commit();
session.close();
System.out.println("successfully saved");
}
}

@Entity marks this class as an Entity

@Table specifies the table name where data of this entity is to be


persisted. If you don't use @Table annotation, Hibernate will use the
class name as the table name by default.
Example ,
@Table(name = "Employee", uniqueConstraints = {
@UniqueConstraint(columnNames = "ID"),
@UniqueConstraint(columnNames = "EMAIL") })

@UniqueConstraint

@Id marks the identifier for this entity

@Column specifies the details of the column for this property or


field. If @Column is not specified, property name will be used as the
column name by default
Example,
@Column(name = "FIRST_NAME", unique = false, nullable = false,
length = 100)

@GeneratedValue annotation is used to specify the primary key generation


strategy to use. If the strategy is not specified by default AUTO
will be used.
Example ,
@GeneratedValue(strategy = GenerationType.IDENTITY)

@OneToMany, @ManyToOne, @ManyToMany, @ManyToOne annotations are


used to create the mapping relationship between two persistent
classes
Attribute cascade=CascadeType.ALL
Example ,

Hibernate
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="EMPLOYEE_ACCOUNT",
joinColumns={@JoinColumn(name="EMPLOYEE_ID",
referencedColumnName="ID")},
inverseJoinColumns={@JoinColumn(name="ACCOUNT_ID",
referencedColumnName="ID")})

@JoinTable annotation is used to create the link table

@JoinColumn annotation is used to refer the linking columns in both


the tables.

@Embeddable annotation is used to specify the persistent class will


be used as a component. This class cannot have a primary key of its
own, it uses the enclosing class primary key.

@Embedded

Generator Classes in Hibernate :

The <generator> sub-element of id used to generate the unique


identifier for the objects of persistent class.

There are many generator classes defined in the Hibernate


Framework.

All the generator classes implements the


org.hibernate.id.IdentifierGenerator interface.

The application programmer may create one's own generator classes


by implementing the IdentifierGenerator interface.

Hibernate framework provides many built-in

generator classes:

1. assigned
2. increment
3. sequence
4. hilo (high and low)
5. native
6. identity
7. seqhilo (high and low with sequence name)
8. uuid
9. guid
10. select
11. foreign
12.

sequence-identity

Hibernate
Inheritance Mapping Concepts :
1. Table Per Hierarchy
2. Table Per Hierarchy using Annotation
3. Table Per Concrete
4. Table Per Concrete using Annotation
5. Table Per Subclass
6. Table Per Subclass using Annotation

1) Discriminator Concepts :
Hibernate Table Per Hierarchy :

By this inheritance strategy, we can map the whole hierarchy by


single table only.

Here, an extra column (also known as discriminator column) is created


in the table to identify the class.

Let's understand the problem first. I want to map the whole hierarchy
given below into one table of the database.

Discriminators are used for storing class hierarchies in a single table

There are three classes in this hierarchy. Employee is the super class
for Regular_Employee and Contract_Employee classes.
Let's

see the mapping file for this hierarchy.

<?xml version='1.0' encoding='UTF-8'?>


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

Hibernate
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.javatpoint.mypackage.Employee" table="emp121"
discriminator-value="emp">
<id name="id">
<generator class="increment"></generator>
</id>
<discriminator column="type" type="string"></discriminator>
<property name="name"></property>

<subclass name="com.javatpoint.mypackage.Regular_Employee"
discriminator-value="reg_emp">
<property name="salary"></property>
<property name="bonus"></property>
</subclass>

Green color data has specified


In hbm files are data base table
column

<subclass name="com.javatpoint.mypackage.Contract_Employee"
discriminator-value="con_emp">
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</subclass>
</class>
</hibernate-mapping>

In case of table per class hierarchy an discriminator column is added by


the hibernate framework that specifies the type of the record.

It is mainly used to distinguish the record.

To specify this, discriminator sub-element of class must be


specified.

The subclass sub-element of class, specifies the subclass. In this


case, Regular_Employee and Contract_Employee are the subclasses of
Employee class.

Hibernate

The <discriminator> element is required for polymorphic persistence


using the table-per-class-hierarchy mapping strategy and declares a
discriminator column of the table.

The discriminator column contains marker values that tell the


persistence layer what subclass to instantiate for a particular
row.

A restricted set of types may be used: string, character, integer, byte,


short, boolean, yes_no, true_false.

2) Hibernate Table Per Hierarchy using Annotation :


Discriminator Concepts using Annotation :
Need to use

@Inheritance(strategy=InheritanceType.SINGLE_TABLE),

@DiscriminatorColumn and @DiscriminatorValue annotations for


mapping table per hierarchy strategy.

In case of table per hierarchy, only one table is required to map the inheritance
hierarchy.
Here, an extra column (also known as discriminator column) is created in
the table to identify the class.
Example,
import javax.persistence.*;
@Entity
@Table(name = "employee101")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type",discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue(value="employee")
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;

Hibernate
//setters and getters
}
import javax.persistence.*;
@Entity
@DiscriminatorValue("regularemployee")
public class Regular_Employee extends Employee{
@Column(name="salary")
private float salary;
@Column(name="bonus")
private int bonus;
//setters and getters
}
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("contractemployee")
public class Contract_Employee extends Employee{
@Column(name="pay_per_hour")
private float pay_per_hour;
@Column(name="contract_duration")
private String contract_duration;
//setters and getters
}
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools.
<hibernate-configuration>
<session-factory>
<property name="hbm2ddl.auto">update</property>

-->

Hibernate
<property
name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property
name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
<property name="connection.username">system</property>
<property name="connection.password">oracle</property>
<property
name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<mapping class="com.javatpoint.mypackage.Employee"/>
<mapping class="com.javatpoint.mypackage.Contract_Employee"/>
<mapping class="com.javatpoint.mypackage.Regular_Employee"/>
</session-factory>
</hibernate-configuration>

3) Table Per Concrete class :


In case of Table Per Concrete class, there will be three tables in the
database having no relations to each other.
There are two ways to map the table with table per concrete class
strategy.

By union-subclass element

By Self creating the table for each class

<?xml version='1.0' encoding='UTF-8'?>


<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.javatpoint.mypackage.Employee" table="emp122">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"></property>

<union-subclass name="com.javatpoint.mypackage.Regular_Employee"
table="regemp122">

Hibernate
<property name="salary"></property>
<property name="bonus"></property>
</union-subclass>

<union-subclass name="com.javatpoint.mypackage.Contract_Employee"
table="contemp122">
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</union-subclass>
</class>
</hibernate-mapping>

The union-subclass sub-element of class, specifies the subclass.

It adds the columns of parent table into this table. In other


words, it is working as a union.

Example,

ID, NAME are


Parent Table Data

4) Table Per Concrete class using annotation :

In case of Table Per Concrete class, tables are created per class.

Hibernate

So there are no nullable values in the table.

Disadvantage of this approach is that duplicate columns are created in the


subclass tables.

Here, we need to use @Inheritance(strategy =


InheritanceType.TABLE_PER_CLASS) annotation in the parent class and
@AttributeOverrides annotation in the subclasses.

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) specifies that


we are using table per concrete class strategy. It should be
specified in the parent class only.

@AttributeOverrides defines that parent class attributes will be


overridden in this class. In table structure, parent class table
columns will be added in the subclass table.

The Same Table structure of TPC with out annotation which has
created here

Example,
import javax.persistence.*;
@Entity
@Table(name = "employee102")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
//setters and getters
}
Example ,
import javax.persistence.*;
@Entity
@Table(name="regularemployee102")
@AttributeOverrides({
@AttributeOverride(name="id", column=@Column(name="id")),
@AttributeOverride(name="name", column=@Column(name="name"))
})
public class Regular_Employee extends Employee{
@Column(name="salary")

Hibernate
private float salary;
@Column(name="bonus")
private int bonus;
//setters and getters
}
Example,
import javax.persistence.*;
@Entity
@Table(name="contractemployee102")
@AttributeOverrides({
@AttributeOverride(name="id", column=@Column(name="id")),
@AttributeOverride(name="name", column=@Column(name="name"))
})
public class Contract_Employee extends Employee{
@Column(name="pay_per_hour")
private float pay_per_hour;
@Column(name="contract_duration")
private String contract_duration;
getters and setters ...
}

5) Table Per Subclass :

In case of Table Per Subclass, subclass mapped tables are related


to parent class mapped table by primary key and foreign key relationship.

The <joined-subclass> element of class is used to map the child class


with parent using the primary key and foreign key relation.

we are going to use hbm2ddl.auto property to generate the table


automatically. So we don't need to be worried about creating tables
in the database.

<?xml version='1.0' encoding='UTF-8'?>


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

Hibernate
<hibernate-mapping>
<class name="com.javatpoint.mypackage.Employee" table="emp123">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"></property>

Parent class
With primary
key
derived class
With foreign key

<joined-subclass name="com.javatpoint.mypackage.Regular_Employee"
table="regemp123">
<key column="eid"></key>
<property name="salary"></property>
<property name="bonus"></property>
</joined-subclass>

derived class
With foreign key

<joined-subclass name="com.javatpoint.mypackage.Contract_Employee"
table="contemp123">
<key column="eid"></key>
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</joined-subclass>
</class>
</hibernate-mapping>

6) Table Per Subclass using Annotation :

In case of table per subclass strategy, tables are created as per


persistent classes but they are related using primary and foreign
key. So there will not be duplicate columns in the relation.

Hibernate

We need to specify @Inheritance(strategy=InheritanceType.JOINED) in the


parent class and @PrimaryKeyJoinColumn annotation in the subclasses.

Example,
@Entity
@Table(name = "employee103")

Parent class

@Inheritance(strategy=InheritanceType.JOINED)
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
//setters and getters
}
@Entity

Derived class

@Table(name="regularemployee103")
@PrimaryKeyJoinColumn(name="ID")
public class Regular_Employee extends Employee{
@Column(name="salary")
private float salary;
@Column(name="bonus")
private int bonus;
//setters and getters
}
@Entity
@Table(name="contractemployee103")
@PrimaryKeyJoinColumn(name="ID")
public class Contract_Employee extends Employee{
@Column(name="pay_per_hour")
private float pay_per_hour;
@Column(name="contract_duration")
private String contract_duration;
//setters and getters}

Derived class

Hibernate

Hibernate Transaction Management


A transaction simply represents a unit of work. In such case, if one step fails,
the whole transaction fails (which is termed as atomicity). A transaction can be
described by ACID properties (Atomicity, Consistency, Isolation and Durability).

Transaction Interface in Hibernate


In hibernate framework, we have Transaction interface that defines the unit of work. It
maintains abstraction from the transaction implementation (JTA, JDBC).
A transaction is associated with Session and instantiated by calling
session.beginTransaction().
The methods of Transaction interface are as follows:

1. void begin() starts a new transaction.


2. void commit() ends the unit of work unless we are in FlushMode.NEVER.
3. void rollback() forces this transaction to rollback.
4. void setTimeout(int seconds) it sets a transaction timeout for any transaction
started by a subsequent call to begin on this instance.

5. boolean isAlive() checks if the transaction is still alive.


6. void registerSynchronization(Synchronization s) registers a user synchronization
callback for this transaction.

7. boolean wasCommited() checks if the transaction is commited successfully.


8. boolean wasRolledBack() checks if the transaction is rolledback successfully.

Hibernate

Example of Transaction Management in Hibernate


In hibernate, it is better to rollback the transaction if any exception occurs, so that resources
can be free. Let's see the example of transaction management in hibernate.
Session session = null;
Transaction tx = null;
try {
session = sessionFactory.openSession();
tx = session.beginTransaction();
//some action
tx.commit();
}catch (Exception ex) {
ex.printStackTrace();
tx.rollback();
}
finally {session.close();}