Вы находитесь на странице: 1из 149

Hibernate Tutorial - Hibernate 3 on Baby Steps

Posted by Dinesh Rajput

This hibernate tutorial provide step by step instructions on using Hibernate 3.0. Hibernate is popular open
source object relational mapping tool for Java platform. It provides powerful, ultra-high performance
object/relational persistence and query service for Java.
Actually Hibernate is much more than ORM Tool (Object - Relational Mapping) because today its provide
lots of features in the persistence data layer.
ORM means Objects to Relational Mapping i.e. Java Persistence Objects are mapped to Relational
databases by using ORM tools.
HIBERNATE :

An ORM Tool

Used in the Data layer of the applications

Implements JPA (Java Persistence API) i.e its have set of standards that have been prescribed
for any persistence of any implementation need to be satisfied to persistence rules in the java that given
minimal change of codes means follow the all rules of persistence in later if any change in the ORM tools
with minimum change in the code.

Why We Have to Use ORM Tools?

Here there is one problem to object save in to relational database each entity of the object save
individually to the database table in the associated columns. It is more times taken and complex in case
of lots of user objects to be save into the database table.

When Inserting into database.


Object's Property ID set to ID column
Object's Property Name set to Name Column
Object's Property Address set to Address Column
Object's Property Phone set to Phone Column
Object's Property Date of Birth set to DOB Column
When Fetching Result Set from Database Table.
Column ID's Value set to Object's ID Property
Column Name's Value set to Object's Name Property
Column Address's Value set to Object's Address Property
Column Phone's Value set to Object's Phone Property
Column DOB's Value set to Object's Date of Birth Property

Hibernate Architecture : Chapter 2


Hibernate Architecture and API

Configuration: It represents a configuration or properties file for Hibernate. The


Configuration object is usually created once during application initialization. The
Configuration object reads and establishes the properties Hibernate uses to get
connected to a database and configure itself for work. A Configuration object is used to
create a SessionFactory and then typically is discarded.
SessionFactory :The SessionFactory is created from a Configuration object, and as its
name implies it is a factory for Session objects.The SessionFactory is an expensive
object to create. It, like the Configuration object, is usually created during application
start up. However, unlike the Configuration object, It should be created once and kept
for later use.
The SessionFactory object is used by all the threads of an application. It is a thread safe
object. One SessionFactory object is created per database. Multiple SessionFactory
objects (each requiring a separate onfiguration) are created when connecting to multiple
databases. The SessionFactory can also provide caching of persistent objects. -Dinesh

Session:Session objects provide the main interface to accomplish work with the
database. Persistent objects are saved and retrieved through a Session object. A
Session object is lightweight and inexpensive to create. A Session object does the work
of getting a physical connection to the database. Session objects maintain a cache for a
single application thread (request).
Session objects are not thread safe. Therefore, session objects should not be kept open
for a long time.Applications create and destroy these as needed. Typically, they are
created to complete a single unit of work, but may span many units. -Dinesh
Transaction: represents unit of works.
Query and Criteria objects are used to retrieve (and recreate) persistent objects.

Setting Up Hibernate3 To Eclipse : Chapter 3

In this tutorial you will see how to configure Hibernate to Eclipse or STS or MyEclipse.
1.
Download Eclipse Latest version and install in your machine.
2.
Download Hibernate3 Latest Version.
3.
Download MySQL database Latest version.
4.
Download JConnector (MySQL Database Driver)
Step 1 : Now open Eclipse you get following window-

Step 2: Go to File->New->Java Project

Step 3: Click on Java Project you will get

Step 4: Click Next -> Finish you will get

Step 5:Right Click on Hibernate Project->go to Property ->Java Build Path->Library->Add Library

Step 6: Click on User Library ->Next->User Libraries..


on New window click on New a pop up of new window is open and fill User Library Name on the Text
Field and Click on OK.

Step 7: Click on Add JARs.. go to specific path of the window where you are save Hibernate Zip file and
add following required jar to your Application

antlr-2.7.6

dom4j-1.6.1

hibernate3

hsqldb

javassist-3.4.GA

jta-1.1

slf4j-api-1.5.6

slf4j-simple-1.5.6

commons-collections-3.1

Finally you will get Hibernate Library in your application

Step 8 : Now install MySQL Database on your machine and add driver library to your application

Go to Project Property->Java Build Path->Library->Add External JARs..->Select Driver jar file>click finish

Now your application fully configured with all required libraries.

First Hibernate Application using Annotation :


Chapter 4
Lets we start on this topics. First we will see what is the process of using database without using
Hibernate.
Saving Without Hibernate ->

JDBC Database configuration

The Model Object

Service method to create the model object

Database Design

DAO method to use saving the model object to the database using SQL queries.
With Hibernate Way->

JDBC Database Configuration -> Hibernate Configuration

The Model Object -> Using Annotation

Service method to create the model object -> Using the Hibernate API

Database Design -> Not Needed

DAO method to use saving the model object to the database using SQL queries -> Not needed
Now as above steps of using hibernate, firstly we have to create Hibernate Configuration file.
Step 1: File Name -> hibernate.cfg.xml in src folder of the application

Now we need to type all the detail related to MySQL database so we can use in our application.
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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->

<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Show all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>
</session-factory>
</hibernate-configuration>
Here below property configure driver of the specific database
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
Next line we configure the Database connection url
suppose we want to connect the database name hibernateDB
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
Next two lines set the user name and password of the connecting database hibernateDB
<property name="connection.username">username</property>
<property name="connection.password">password</property>
Next line configure Dialect of the database MySQL, every database has its own Dialect.
What is Dialect? means Dialect is configuration specify here so hibernate knows whats kind of language
we are used and what type database we are used. we can say it is database dependent. It connects the
database specific query language which we want to use.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
The below line configured the model class name UserDetails its object we want save on the
database hibernateDB
<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>
Now step 1 is over now we move to another step Now we have to create a Model class
Step 2: UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class UserDetails
{
@Id
private int userId;
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {

this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Here @Entity means it telling hibernate this class treat as entity and need to save it the database.
and @ID means it telling hibernate this property treat as primary key of the table.
these are two minimum required annotation we have use for saving the object in the database.
Now we move to next step create service method to save the model object in the database.
Using the Hibernate API

Create a session factory

create a session from the session factory

Use the session to save model objects


Step 3: HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
public static void main(String[] args)
{
//Create the model object
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Dinesh Rajput");
// Create Session Factory Object using Annotation Configuration
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
//Create Session object from session factory object
Session session = sessionFactory.openSession();
session.beginTransaction();
//Use the session to save model objects
session.save(user);
session.getTransaction().commit();
session.close();
}
}
Now run application now we get a Table with name UserDetails as its model class name with
two columns name are ID andUserName as class property name.

Next Chapter we will write hibernate application using mapping file for the model class

First Hibernate Application Using Mapping File


: Chapter 5
In this chapter we will learn about how to use configuration file of the model class in stead of Annotation
as used in the previous chapter and also learn about how to define model class property in the XML
configuration fine or object mapping file(.hbm.xml).
As previous chapter we have write the model class UserDetalis.java
package com.sdnext.hibernate.tutorial.dto;
public class UserDetails
{
private int userId;
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}

Mapping the UserDetalis Object to the Database UserDetails table


The file userdetails.hbm.xml is used to map userDetail Object to the UserDetails table in the database.
Here is the code foruserdetails.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.UserDetails" table="UserDetails">
<id name="userId" type="long" column="ID" >
<generator class="assigned"/>
</id>
<property name="userName">
<column name="UserName" />
</property>
</class>
</hibernate-mapping>
Configuring Hibernate: here some change is required in the configuration file because we are used
mapping file in stead of Annotation.
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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Show all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- Mapping files -->
<mapping resource="userdetails.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Here we are used mapping resource


<mapping resource="userdetails.hbm.xml"/>
in stead of mapping class.
<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>
Developing Code to Test Hibernate example:
Now there are three steps for using Hibernate API

Create the session factory

Create the session object from the session factory

Saving the model object using session object


HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
public static void main(String[] args)
{
//Create the model object
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Dinesh Rajput");
// Create Session Factory Object - using configuration object
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
//Create Session object from session factory object
Session session = sessionFactory.openSession();
session.beginTransaction();
//Use the session to save model objects
session.save(user);
session.getTransaction().commit();
session.close();
}
}
Now you can run the application and see the result.
So in this topic we see how to use Mapping file to map the Model Object to relational database table.

In the Next Chapter We will Described the O/R Mapping file in details.

What is Hibernate O/R Mapping : Chapter 6


Hello Friends In Last chapters you learned about how to write our first hibernate application, there are two
approach we have used for that--1.
Using Annotation for Model Class Object Mapping

2.
Another way Using Hibernate O/R Mapping file(.hbm.xml) for Model Class Object
Mapping.
In the last example we created userDetails.hbm.xml to map UserDetails Object to
the UserDetails table in the database. Now let's understand the each component of the mapping file.
To recall here is the content of userDetails.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.UserDetails" table="UserDetails">
<id name="userId" type="long" column="ID" >
<generator class="assigned"/>
</id>
<property name="userName">
<column name="UserName" />
</property>
</class>
</hibernate-mapping>
1.<hibernate-mapping> element:
The first or root element of hibernate mapping document is <hibernate-mapping> element. Between the
<hibernate-mapping> tag class element(s) are present.
2. <class> element:
The <Class> element maps the class object with corresponding entity in the database. It also tells what
table in the database has to access and what column in that table it should use. Within one <hibernatemapping> element, several <class> mappings are possible.
3.<id> element:
The <id> element in unique identifier to identify an object. In fact <id> element map with the primary key
of the table. In our code :
<id name="userId" type="long" column="ID" >
primary key maps to the ID field of the table UserDetails. Following is the attributes of <id> element

name - Property name of the persistence model class

type - The java data type used for that property

column - Name of the column for that property of the persistence object

unsaved-value - This is the value used to determine if a class has been made persistent. If the
value of the id attribute is null, then it means that this object has not been persisted.
4.<generator> element:
Used to create primary key for new record, there are some commonly used generators type given below...

Increment- used to generate primary keys of type long, short or int that are unique only.

Sequence - used to generate primary keys for DB2, Oracle, SAP Database.

Assigned - is used when application code generates the primary key.

Native

- selects identity, sequence or hilo depending upon the capabilities of the underlying db.


Identity - supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL.
The returned identifier is of type long, short or int.

Uuid - Unique use ID of 128 bits generated from using algorithm and return type is String

hilo - generated by the hi/lo Algorithm

seqhilo - generated by the hi/lo Algorithm according to sequence of database

select - select from database triggered value

foreign - associated with the other model objects

5.<property> element: define standard Java attributes and their mapping into database schema.
That is all about the mapping file for O/R mapping. I hope you was understand its all elements and its
working in the hibernate.

Using Annotations in Hibernate vs


Configuration files : Chapter 8
ANNOTATIONS VS. XML
Since Java adopted annotations, Ive heard a lot of discussion around whether to prefer annotations over
external configuration files (often XML) and vice versa.

I think the decision boils down to two criteria:


1) Can annotations simplify the metadata?
2) Can changes to the metadata break behavior in your application?
If annotations do not reduce the amount of metadata that you have to provide (in most cases they do),
then you shouldnt use annotation.
For example, Hibernate mappings are often in XML, but annotations often provide the ability to specify
the same mappings with significantly less metadata. Any changes you make to your mappings (whether
in XML or annotations) could potentially be behavior breaking. Youre not going to change your mappings
dynamically at run-time, are you? So, annotations seem like a much better choice.
[Note: I might consider using XML metadata for Hibernate when mapping to a legacy database because
the annotations can often become bulky. Also, you are forced to use XML if you want to map the classes
against two different databases with different schema. I haven't heard of a way to specify two mutually
exclusive sets of Hibernate annotations on my classes. Even if this did exist it would be complex, which
violates my first criterion for selecting annotations over XML.]

MAPPING:

Mapping file is the heart of hibernate application.

Every ORM tool needs this mapping, mapping is the mechanism of placing an object properties
into columns of a table.


Mapping can be given to an ORM tool either in the form of an XML or in the form of the
annotations.

The mapping file contains mapping from a pojo class name to a table name and pojo class
variable names to table column names.

While writing an hibernate application, we can construct one or more mapping files, mean a
hibernate application can contain any number of mapping files.
generally an object contains 3 properties like

Identity (Object Name)

State (Object values)

Behavior (Object Methods)


But while storing an object into the database, we need to store only the values(State) right ? but how to
avoid identity, behavior.. its not possible. In order to inform what value of an object has to be stored in
what column of the table, will be taking care by the mapping, actually mapping can be done
using 2 ways,

XML

Annotations.
Actually annotations are introduced into java from JDK 1.5

Now we will look how to relate XML Mapping to Annotation


Mapping a class UserDetails to Table USER_DETAIL in XML -<class name="com.sdnext.hibernate.tutorial.dto.UserDetails" table="USER_DETAIL">

Now Mapping a class UserDetails to Table USER_DETAIL in Annotation -@Entity


@Table (name="USER_DETAIL")
public class UserDetails{}

here @Entity declares the class as an entity (i.e. a persistent POJO class)
@Table is set at the class level; it allows you to define the table, catalog, and schema names for your
entity mapping. If no@Table is defined the default values are used: the unqualified class name of the
entity.
Mapping primary key USER_ID of table to property userId of class UserDetails in XML
<id name="userId" type="long" column="USER_ID" >

Mapping primary key USER_ID of table to property userId of class UserDetails in Annotation
@Entity
@Table (name="USER_DETAILS")
public class UserDetails
{
@Id
@Column(name="USER_ID")

private long userId;


}
here @Id declares the identifier property of this entity. The class UserDetails is mapped to
the USER_TABLE table, using the column USER_ID as its primary key column.
The column(s) used for a property mapping can be defined using the @Column annotation. Use it to
override default values .
Id Generator Class Mapping in XML
<id name="userId" type="long" column="USER_ID" >
<generator class="auto"/>
</id>

Id Generator Class Mapping in Annotation


@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private long userId;
Different GenerationType Enum Properties....

AUTO - either identity column, sequence or table depending on the underlying DB

TABLE - table holding the id

IDENTITY - identity column

SEQUENCE - sequence

identity copy - the identity is copied from another entity

@GeneratedValue Provides for the specification of generation strategies for the values of primary keys.
Enum GenerationType Defines the types of primary key generation strategies.
Mapping Column to the property of class in XML
<property name="userName" column="USER_NAME">

Mapping Column to the property of class in Annotation


@Column(name="USER_NAME")
private String userName;
@Column- provides the name of the column in a table if it is different from the attribute name. (By
default, the two names are assumed to be the same.)
More JPA Annotations for Class Field:
@Basic - The use of the Basic annotation is optional for persistent fields and properties of these types.
If the Basic annotation is not specified for such a field or property, the default values of
the Basic annotation will apply. Example-

@Basic
private String userName;
@Transient - using when if you want skip any field of entity class to save in the database. Example@Transient
private String middleName;
@Embedded- using when if property or field of persistence class is Embeddable persistence class.
Example- class Address{ @Column(name="STREET")

@Embedded
private Address address;
@ElementColllection- Defines a collection of instances of a basic type or embeddable class. Must be
specified if the collection is to be mapped by means of a collection table. Example@ElementCollection
private Collection<Address> lisOfAddresses = new ArrayList<Address>();
@Id- Specifies the primary key of an entity. Example@Id
private long userId;
@EmbeddedId- composite primary key of an embeddable class. Example@Embeddable
Class Address{
@EmbeddedId
private int addressId;
------}
@Version- Specifies the version field or property of an entity class that serves as its optimistic lock value.
The version is used to ensure integrity when performing the merge operation and for optimistic
concurrency control. Example-

@Version
private int addressId;
@Temporal- This annotation must be specified for persistent fields or properties of
type java.util.Date andjava.util.Calendar. Example@Column(name="JOIN_DATE")
@Temporal(TemporalType.DATE)
private Date joinDate;

Here we will learn about hbm2ddl Configuration in the hibernate configuration file (hibernate.cfg.xml).
Actually hbm2ddl Configuration means hibernate mapping to create schema DDL (Data Definition
Language).
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
Automatically validates or exports schema DDL to the database when the SessionFactory is created.
With create-drop, the database schema will be dropped when the SessionFactory is closed
explicitly.
<?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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Show all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>

<!-- Mapping files -->


<mapping resource="userdetails.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Here <property name="hbm2ddl.auto">create</property> means schema DDL created every time
when SessionFactory Object is created.
UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Entity;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="USER_TABLE")
public class UserDetails
{
@Id
@Column(name="USER_ID")
private int userId;
@Column(name="USER_NAME")
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Now we run this example-public class HibernateTestDemo {
public static void main(String[] args)
{
//Create the model object
UserDetails user1 = new UserDetails();
UserDetails user2 = new UserDetails();
user1.setUserId(1);
user1.setUserName("Dinesh Rajput");
user2.setUserId(2);
user2.setUserName("Anamika Rajput");

// Create Session Factory Object - using annotation configuration object


SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
//Create Session object from session factory object
Session session = sessionFactory.openSession();
session.beginTransaction();
//Use the session to save model objects
session.save(user1);
session.save(user2);
session.getTransaction().commit();
session.close();
}
}
Run this example-log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_DETAILS ( USER_ID, USER_NAME) values (?, ?)
Hibernate: insert into USER_DETAILS ( USER_ID, USER_NAME) values (?, ?)
Now we get following table structure--

Again we running the following examplepublic class HibernateTestDemo {


public static void main(String[] args)
{
//Create the model object
UserDetails user1 = new UserDetails();
UserDetails user2 = new UserDetails();
user1.setUserId(3);
user1.setUserName("Dev Rajput");
user2.setUserId(4);
user2.setUserName("Sweety Rajput");
// Create Session Factory Object - using annotation configuration object
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
//Create Session object from session factory object
Session session = sessionFactory.openSession();
session.beginTransaction();
//Use the session to save model objects
session.save(user1);
session.save(user2);

session.getTransaction().commit();
session.close();
}
}
Run this example-log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_DETAILS ( USER_ID, USER_NAME) values (?, ?)
Hibernate: insert into USER_DETAILS ( USER_ID, USER_NAME) values (?, ?)
Now we get the following table schema--

Here we see that the previous data is destroyed when we are using in the hibernate.cfg.xml file using
the following line.
<property name="hbm2ddl.auto">create</property>
Here
hbm2ddl.auto-->create -Always create new schema
hbm2ddl.auto-->update -Update existing schema
Now we are replacing above line with the <property name="hbm2ddl.auto">update</property>
public class HibernateTestDemo {
public static void main(String[] args)
{
//Create the model object
UserDetails user1 = new UserDetails();
UserDetails user2 = new UserDetails();
user1.setUserId(1);
user1.setUserName("Dinesh Rajput");
user2.setUserId(2);
user2.setUserName("Anamika Rajput");
// Create Session Factory Object - using annotation configuration object
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
//Create Session object from session factory object
Session session = sessionFactory.openSession();
session.beginTransaction();
//Use the session to save model objects
session.save(user1);
session.save(user2);
session.getTransaction().commit();
session.close();
}
}

Run this example-log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).


log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_DETAILS ( USER_ID, USER_NAME) values (?, ?)
Hibernate: insert into USER_DETAILS ( USER_ID, USER_NAME) values (?, ?)
Now we get the following table schema...

here we are looking the table USER_DETAILS only updated not again created.

Retrieving Objects in Hibernate using


session.get : Chapter 10
We'll look at one of the several ways we can fetch data from the database using Hibernate:
the session.get method.
Now look following example...
UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table (name="USER_TABLE")
public class UserDetails
{
@Id
@Column(name="USER_ID")
private int userId;
@Column(name="USER_NAME")
private String userName;
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}

public void setUserName(String userName) {


this.userName = userName;
}
public String toString()
{
return "[User Name: "+userName+"User Id: "+userId+"]";
}
}
This is user domain persistence class UserDetails to store data into table USER_TABLE with columns
name USER_ID and USER_NAME corresponding persisting field userId and userName respectively.
Now we have to configure hibernate configuration file.
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>

</session-factory>
</hibernate-configuration>
here we are using MySql database hibernateDB. Now we running the code with following class file
HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails(); //Creating first user
user.setUserId(1);
user.setUserName("Dinesh Rajput");
UserDetails user2 = new UserDetails();//Creating second user
user2.setUserId(2);
user2.setUserName("Anamika Rajput");
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); //Creating a session factory object
Session session = sessionFactory.openSession(); //Creating a session object for inserting
users object to the database table USER_TABLE
session.beginTransaction(); //Open the transaction of session object to do something
session.save(user); //Inserting or Saving the first user
object
session.save(user2); //Inserting or Saving the second user object
session.getTransaction().commit();//Close the transaction of session object after to do
something
session.close(); //Close the session object performing saving event to database
user = null; //Now getting a user object from database table from session object
session = sessionFactory.openSession(); //Creating a new session object for fetching user
object
session.beginTransaction(); //Again Open the transaction of the session object
user = (UserDetails) session.get(UserDetails.class, 1); //we get user object from session object
using method session.get(Class arg1, Serializable arg2) here arg2 is primary key or id of the
fetching object and arg1 is the what the model object we want to retrieve from database.

System.out.println(user);
}
}
Here after running this code we get following output...
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_TABLE (USER_NAME, USER_ID) values (?, ?)
Hibernate: insert into USER_TABLE (USER_NAME, USER_ID) values (?, ?)
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_
from USER_TABLE userdetail0_ where userdetail0_.USER_ID=?
[User Name: Dinesh Rajput User Id: 1]

Hibernate Update Query : Chapter 11


In this tutorial we will show how to update a row with new information by retrieving data from the
underlying database using the hibernate. Lets first write a java class to update a row to the database.
Create a java class:
here we update the value of the field name userName with corresponding column name
is USER_NAME in the database tableUSRE_TABLE.

In the above table we want to update the value of the USER_NAME column of the USER_TABLE table
associated user model object which userId = 2
current value of the userName is 'Anamika Rajput' update to userName='Sweety'.
Look the following class file.
HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = null;
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
user = (UserDetails) session.get(UserDetails.class, 2); //Retrieving object which we want to update
user.setUserName("Sweety"); //Set the updated userName to the model field
session.update(user); //Update to the database table
session.getTransaction().commit();
System.out.println("Updated User ->"+user);
session.close();
}
}
Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_
from USER_TABLE userdetail0_ where userdetail0_.USER_ID=?
Hibernate: update USER_TABLE set USER_NAME=? where USER_ID=?
[Updated User -> User Name: Sweety User Id: 2]

Now we get the following updated table...

We are looking the value of the USER_NAME column updated from 'Anamika Rajput' to 'Sweety' in
the USER_TABLE table.

Hibernate Delete Query : Chapter 12


In this lesson we will show how to delete rows from the underlying database using the hibernate. Lets first
write a java class to delete a row from the database.
Create a JAVA Class for this:
here we give the code of java class HibernateTestDemo.java which we will delete a row from the
USER_TABLE table using the query
"delete from USER_TABLE where USER_ID = 2"

Following is USER_TABLE:

package com.sdnext.hibernate.tutorial;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();

session.beginTransaction();
String sql = "DELETE FROM UserDetails WHERE USER_ID = 2";
Query query = session.createQuery(sql);
int row = query.executeUpdate();
if (row == 0)
System.out.println("Doesnt deleted any row!");
else
System.out.println("Deleted Row: " + row);
session.getTransaction().commit();
session.close();
}
}
Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: delete from USER_TABLE where USER_ID=2
Deleted Row: 1

Now we look the following table structure---

Value Types & Embedding Objects in


Hibernate : Chapter 13

Well learn the difference between Entity type objects and Value type objects. Well use
the @Embeddable annotations to embed a value type object into our Entity class.
"An object of value type has no database identity; it belongs to an entity instance and its persistent
state is embedded in the table row of the owning entity. Value types don't have identifiers or identifier
properties"
Now In short we look the following points...

Object of Entity Type : has its own database identity

Object of Value Type : belongs to an entity, and its persistent state is embedded in the table row
of the owning entity. Value types don't have identifiers or identifier properties.
We look following example of Object of Entity Type:
@Entity
@Table(name="USER_TABLE")
public class UserDetails{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="USER_ID", type="INTEGER")
private long userId;
@Column(name="USER_NAME", type="String")
private String userName;
@Column(name=USER_ADDRESS, type="String")
private String address;
@Column(name="USER_PHONE", type="INTEGER")
private long phone;
@Column(name="DOB", type="TIMESTAMP")
private Date dob;
}

In Above table we saw that type of the all fields of the class USER CLASS have database entity type
object.
ID
is INTEGER type
Name
is VARCHAR type
ADDRESS is VARCHAR type
Phone
is BIG INTEGER type
DOB
is TIMESTAMP type
All are the Entity Type Objects.
Now We look following example of Object of Value Type:

@Entity
@Table(name="USER_TABLE")
public class UserDetails{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="USER_ID", type="INTEGER")
private long userId;
@Column(name="USER_NAME", type="String")
private String userName;
@Column(name=USER_ADDRESS, type="??????") //What should be type for database
private Address address;
@Column(name="USER_PHONE", type="INTEGER")
private long phone;
@Column(name="DOB", type="TIMESTAMP")
private Date dob;
}
Now lets see table structure for that...

here USER CLASS have a field Address type of the Value type object means in the database there are
no meaning of Address type object.
Address type object have the four other fields like.
1. Street
2. City

3. State
4. Pin code
VALUE TYPE OBJECT APPROACH:>
Here there are one approach to save the value the Address Object save to the USER TABLE is the save
the individually fields of this object to the separate columns of the USER TABLE. As following

This scenario is working in the hibernate only one condition is Address Object should be a Value Object
(means there is no meaning to itself its provide the meaning to the entity object).
In this approach there are some problems are
1. Table complexity
2. Data Redundancy
3. User may have multiple Address like home address and office address etc.
Look the above example in the code...
Address.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable //for value object it is not is entity object. Value object means does not have real
meaning for self individually.

public class Address


{
@Column(name="STREET_NAME")
private String street;
@Column(name="CITY_NAME")
private String city;
@Column(name="STATE_NAME")
private String state;
@Column(name="PIN_CODE")
private String pincode;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPincode() {
return pincode;
}
public void setPincode(String pincode) {
this.pincode = pincode;
}
public String toString()
{
return " {Street: "+street+" City: "+city+" State: "+state+" Pincode: "+pincode+" }";
}
}
@Embeddable:
Target:
Classes
Defines a class whose instances are stored as an intrinsic part of an owning entity and share the
identity of the entity. Each of the persistent properties or fields of the embedded object is mapped
to the database table for the entity.
UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table (name="USER_TABLE")
public class UserDetails
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="USER_ID")
private int userId;
@Column(name="USER_NAME")
private String userName;
@Embedded //For value type object
private Address address;
@Column(name="USER_PHONE")
private String phone;
@Column(name="DOB")
private Date dob;
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public int getUserId() {
return userId;
}
public String toString()

{
return "[User Name: "+userName+"User Id: "+userId+" User Address "+address+" Use phone "
+phone+" ]";
}
}
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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>
</session-factory>
</hibernate-configuration>

HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;

public class HibernateTestDemo {


/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user1 = new UserDetails(); //create first user
UserDetails user2 = new UserDetails(); //create second user
user1.setUserName("Dinesh Rajput");
user2.setUserName("Anamika Rajput");
Address address1 = new Address(); //create first value type object for entity type object user1
address1.setStreet("K Block House No. 403");
address1.setCity("Mangol Puri");
address1.setState("New Delhi");
address1.setPincode("110083");
user1.setAddress(address1);
Address address2 = new Address();//create second value type object for entity type object user2
address2.setStreet("Film City");
address2.setCity("Noida");
address2.setState("UP");
address2.setPincode("201301");
user2.setAddress(address2);
user1.setDob(new Date());
user1.setPhone("+91-9953423462");
user2.setDob(new Date());
user2.setPhone("+91-9973423462");
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); //create a session factory object
Session session = sessionFactory.openSession(); // create session object from session factory
session.beginTransaction(); //begin transaction for this session
session.save(user1); //save the first user
session.save(user2); //save the second user
session.getTransaction().commit(); //commit the transaction the session
session.close(); //close the session
}
}

OUTPUT:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_TABLE (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME, DOB,
USER_PHONE, USER_NAME) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_TABLE (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME, DOB,
USER_PHONE, USER_NAME) values (?, ?, ?, ?, ?, ?, ?)

Attributes Override:
Here we have seen that an Entity Type Object USER has a Value Type Object(or Embeddable Object )
ADDRESS with corresponding fields name street, city, pin-code and state save to the database table
USER_TABLE with value type object's column name (CITY_NAME, PIN_CODE, STATE_NAME,
STREET_NAME).
But here some problems, suppose this user object have two types of addresses as like Local Address
and Permanent Address then how to manage the column names of these value type objects in the
database table USER_TABLE.
To overcome this problem we have to override the Attributes of the Value type objects.
Lets see how to get in the code...
UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
@Entity
@Table (name="USER_TABLE")public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")

private String userName;


@Column(name="DOB")
private Date joinDate;
@Column(name="ADDRESS")
@Embedded
@AttributeOverrides({
@AttributeOverride(name="street", column=@Column(name="HOME_STREET_NAME")),
@AttributeOverride(name="city", column=@Column(name="HOME_CITY_NAME")),
@AttributeOverride(name="state", column=@Column(name="HOME_STATE_NAME")),
@AttributeOverride(name="pincode", column=@Column(name="HOME_PIN_CODE"))})
private Address homeAddress;
@Embedded
private Address permanentAddress;
@Column(name="Phone")
private String phone;
public int getUserId() {
return userId;
}
public Address getHomeAddress() {
return homeAddress;
}
public void setHomeAddress(Address homeAddress) {
this.homeAddress = homeAddress;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob= dob;
}
public Address getPermanentAddress() {
return permanentAaddress;
}
public void setPermanentAddress(Address permanentAddress) {
this.permanentAddress = permanentAddress;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone= phone;
}

public String toString()


{
return "[User Name: "+userName+"\n Permanent Address: "+permanentAddress+"\n Home Address:
"+homeAddress+"\n Date of Birth: "+dob+"\n Phone: "+phone+"]";
}
}
Now run the following code of the class file..
HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;

public class HibernateTestDemo {


/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails(); //create an user is entity type object
//user.setUserId(1);
user.setUserName("Dinesh Rajput");
Address address = new Address(); //create an value type object of address class for home address
address.setStreet("Block House No");
address.setCity("MangolaPuri");
address.setState("New Delhi");
address.setPincode("110089");
user.setHomeAddress(address); //set the home address
Address address1 = new Address();//create another value type object for the permanent address
address1.setStreet("Film City");
address1.setCity("Noida");
address1.setState("UP");
address1.setPincode("201301");
user.setPermanentAddress(address1);//set the permanent address
user.setDob(new Date());
user.setPhone("9999222211");
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); //create a session factory object
Session session = sessionFactory.openSession(); //create a session object
session.beginTransaction(); //transaction object start
session.save(user); // save the entity type object user to the database

session.getTransaction().commit(); //commit the transaction object


session.close(); //close the session
}
}
After running the above code we will get the following table structure...

Saving Collections in Hibernate : Chapter 14


Now well learn about the Collection in the hibernate.
In previous chapter we learned about Embedding value type object.
Now what will be do when there are a lots of embeddable objects instead of the single embeddable
objects, In previous we have used two embeddable objects in the UserDetails class.

Suppose we want to keep tracks all addresses of an user, so think about one minute how to get.
Lets we will using the Collection for that.
1. In this code snip User has one address
class UserDetails{
----private int userId;
----private Address address;
----}

2. In this code snip User has two addresses


class UserDetails{
----private int userId;
-----

private Address address1;


private Address address2;
----}

3. In this code snip User has more than two addresses


class UserDetails{
----private int userId;
----private Address address1;
private Address address2;
----private Address addressN;
----}
In third case how to manage the records about addresses for that user, now for managing this type of
problems we have to use the collection, we do not need to care about how many of the addresses user
have. Lets see there are same change in the code for that...

class UserDetails{
----private int userId;
----private List<Address> addresses = new ArrayList<Address>();
----}

Hibernate provides the facility to persist the collections. A collection can be a list, set, map, collection,
sorted set, sorted map. java.util.List, java.util.Set, java.util.Collection, java.util.SortedSet,
java.util.SortedMap etc. are the real interface types to declared the persistent collection-value fields.
Hibernate injects the persistent collections based on the type of interface. The collection instances usually
behave likes the types of value behavior. Instances of collections are auto persisted if a persistent object
refers it and are deleted automatically if it is not referred through. Elements of collection may shift from
one table to another when a persistent object passed the collection to another persistent object.

We look following example of Object of Entity Type:


@Entity
@Table(name="TBL_USER_DETAILS")
public class UserDetails{
@Id
@Column(name="USER_ID", type="INTEGER")
@GeneratedValue(strategy=GenerationType.AUTO)
private long userId;
@Column(name="USER_NAME", type="String")
private String userName;
@ElementCollection
private Collection<Address> lisOfAddresses = new ArrayList<Address>();
public Collection<Address> getLisOfAddresses() {
return lisOfAddresses;
}
public void setLisOfAddresses(Collection<Address> lisOfAddresses) {
this.lisOfAddresses = lisOfAddresses;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String toString()
{
return "[User Name: "+userName+"\n Office Address: "+lisOfAddresses+"]";

}
}

@ElementCollection:
Target:
Fields (including property get methods)
Defines a collection of instances of a basic type or embeddable class. Must be specified if the
collection is to be mapped by means of a collection table.

Address.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable //for value object it is not is entity object. Value object means does not have real meaning
for self individually.
public class Address
{
@Column(name="STREET_NAME")
private String street;
@Column(name="CITY_NAME")
private String city;
@Column(name="STATE_NAME")
private String state;
@Column(name="PIN_CODE")
private String pincode;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;

}
public void setState(String state) {
this.state = state;
}
public String getPincode() {
return pincode;
}
public void setPincode(String pincode) {
this.pincode = pincode;
}
public String toString()
{
return " {Street: "+street+" City: "+city+" State: "+state+" Pincode: "+pincode+" }";
}
}
hibernate.cfg.xml will be the same as the previous chapter.

HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails();//Create user object
user.setUserName("Dinesh Rajput"); //Set user name
Address address1 = new Address(); // create first embedded object address
address1.setStreet("First Street");
address1.setCity("First City");
address1.setState("First State");
address1.setPincode("First Pin");

Address address2 = new Address(); // create second embedded object address


address2.setStreet("Second Street");
address2.setCity("Second City");
address2.setState("Second State");
address2.setPincode("Second Pin");
//adding addresses object to the list of address
user.getLisOfAddresses().add(address1);
user.getLisOfAddresses().add(address2);
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); //create session factory object
Session session = sessionFactory.openSession(); //create session object from the session factory
session.beginTransaction(); //initialize the transaction object from session
session.save(user); // save the user
session.getTransaction().commit(); //commit the transaction
session.close(); //closing session
}
}
Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into TBL_USER_DETAILS (USER_NAME) values (?)
Hibernate: insert into TBL_USER_DETAILS_lisOfAddresses (TBL_USER_DETAILS_USER_ID,
CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?)
Hibernate: insert into TBL_USER_DETAILS_lisOfAddresses (TBL_USER_DETAILS_USER_ID,
CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?)

Look care fully to the output line, there are two tables here in the database, first for the UserDetails entity
"TBL_USER_DETAILS" and second for the embeddable object Address name is
"TBL_USER_DETAILS_lisOfAddresses " (this is default name of table for address Entity Table
Name_field name of the list of the embeddable object in the entity class).

Here see that there is one table for the address object created separate for the collection.
1. First Table TBL_USER_DETAILS

2. Second Table TBL_USER_DETAILS_lisOfAddresses

In the second table first column TBL_USERS_DETAILS_USER_ID has the user id is foreign key for this
table and primary key of the TBL_USER_DETAILS table.

Using Collections in Hibernate & Adding Keys :


Chapter 15
In previous chapter we wrote the collection of objects of an entity class, we persist in the separate table,
here there are following two tables are created in the database

1. TBL_USER_DETAILS for UserDetails entity type object


2. TBL_USER_DETAILS_lisOfAddresses for Address value type object

In this chapter we will explore some advanced options about the collection.
Now we see first thing is the name of the table.

TBL_USER_DETAILS_lisOfAddresses is name for the collection table it is not very user friendly name.

To overcome this problem we will use annotation @JoinTable.

@JoinTable:
Target:
Fields (including property get methods)
Used in the mapping of associations. It is specified on the owning side of an association.
A join table is typically used in the mapping of many-to-many and unidirectional one-to-many
associations. It may also be used to map bidirectional many-to-one/one-to-many associations,
unidirectional many-to-one relationships, and one-to-one associations (both bidirectional and
unidirectional).
When a join table is used in mapping a relationship with an embeddable class on the owning side of the
relationship, the containing entity rather than the embeddable class is considered the owner of the
relationship.
If the JoinTable annotation is missing, the default values of the annotation elements apply. The name of
the join table is assumed to be the table names of the associated primary tables concatenated together
(owning side first) using an underscore.
@Entity
@Table (name="USERS_DETAILS")
public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
@ElementCollection
@JoinTable(name="USER_ADDRESS")//name of the table is changed to USER_ADDRESS
private Collection<Address> lisOfAddresses = new ArrayList<Address>();
}

After running the above code the following output string show the updated table name of the collection
table.
Now we see that the name of the column of this table which have the foreign key user id is
the USER_DETAILS_USER_ID is not also very user friendly, for this look to the following updated code
of the UserDetails entity class. Here we used annotation@JoinColumn.
@JoinColumn:
Target:

Fields (including property get methods)


Specifies a column for joining an entity association or element collection. If the JoinColumn annotation
itself is defaulted, a single join column is assumed and the default values apply.
@JoinColumns:
Target:
Fields (including property get methods)
Defines mapping for composite foreign keys. This annotation groups JoinColumn annotations for the
same relationship. When theJoinColumns annotation is used, both the name and
the referencedColumnName elements must be specified in each suchJoinColumn annotation.

@Entity
@Table (name="USERS_DETAILS")
public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
@ElementCollection
@JoinTable(name="USER_ADDRESS",
joinColumns=@JoinColumn(name="USER_ID"))
private Collection<Address> lisOfAddresses = new ArrayList<Address>();
}

Look the following snap of the output..

Now we look for how to adding key to the collection table.


UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
import org.hibernate.annotations.CollectionId;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
@Entity
@Table (name="USER_DETAIL")
public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
@ElementCollection
@JoinTable(name="USER_ADDRESS",
joinColumns=@JoinColumn(name="USER_ID"))
@GenericGenerator(strategy="hilo", name = "hilo-gen")
@CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "hilo-gen", type =
@Type(type="long"))
private Collection<Address> lisOfAddresses = new ArrayList<Address>();
public Collection<Address> getLisOfAddresses() {
return lisOfAddresses;
}
public void setLisOfAddresses(Collection<Address> lisOfAddresses) {
this.lisOfAddresses = lisOfAddresses;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;

}
public void setUserName(String userName) {
this.userName = userName;
}
public String toString()
{
return "[User Name: "+userName+"\n Office Address: "+lisOfAddresses+"]";
}
}

Address.java and hibernate.cfg.xml is the same as previous chapter.

HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails();
//user.setUserId(1);
user.setUserName("Dinesh Rajput");
Address address1 = new Address();
address1.setStreet("First Street");
address1.setCity("First City");
address1.setState("First State");
address1.setPincode("First Pin");
Address address2 = new Address();
address2.setStreet("Second Street");
address2.setCity("Second City");
address2.setState("Second State");
address2.setPincode("Second Pin");
user.getLisOfAddresses().add(address1);
user.getLisOfAddresses().add(address2);

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


Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
}
}
Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_DETAIL (USER_NAME) values (?)
Hibernate: insert into USER_ADDRESS (USER_ID, ADDRESS_ID, CITY_NAME, PIN_CODE,
STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, ADDRESS_ID, CITY_NAME, PIN_CODE,
STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?, ?)

Tables:

Proxy Objects and Eager & Lazy Fetch Types


in Hibernate : Chapter 16
In this tutorial we look what is proxy object and how hibernate provide the proxy object for us and also we
look about some fetching strategies.

So we first look about the proxy object.


Hibernate Proxy Object: An object proxy is just a way to avoid retrieving an object until you need it.

In our example user class has the three field values1. User Id
2. User Name
3. List of the Addresses

If you want retrieve user object from the database, so what field value are retrieved from the database
and which field are initialized. Suppose one user XYZ has the 100 addresses in the database and we
want to retrieved the name of this user from database. For that we retrieve the user object, now question
is this what about the field listOfAddress field, Is it also have the value? if you say yes so what about
cost of memory ? if you say no so how to retrieve the value associated with that field the address table in
the database on demand.
-A
|
*---B
|
|
|
*---C
|
|
|
*---D
|
|
|
*---E
|
|
|
*---F
|
|
|
*---G
*---H
Ok lets see in the given below flow of the diagram.

In Hibernate 2 does not proxy objects by default. However, experience has shown that using object
proxies is preferred, so this is the default in Hibernate 3.

In Hibernate 3, when we fetching the user object from the database actually its retrieved the proxy object
of the user class means only first level of the fields are initializing with the associated values from the
database. Field listOfAddresses does not have the value. If you want the list address you should call the
following method you will get the listOfAddresses.
user.getListOfAddress(); --->> this return the list of the address associated
with that particular user which name is XYZ this is the default behavior of the Hibernate 3.
Now we look about the fetching strategies.
Fetching Strategies: there are two types of the fetching strategies in the hibernate.
1. Lazy Fetch type
2. Eager Fetch type
LAZY = fetch when needed
EAGER = fetch immediately

1. Lazy Fetch Type: This the default fetch type of the hibernate 3.
Now when you load a User from the database, JPA loads its id, name, and address fields for you. But you
have two options for users: to load it together with the rest of the fields (i.e. eagerly) or to load it ondemand (i.e. lazily) when you call the user'sgetListOfAddresses() method.
Lazy/Select Fetch strategy:- Select Fetch strategy is the lazy fetching of associations. The purpose of
Lazy strategy is memory optimization . When I say memory optimization it means it means it saves us

from heap error. This is what I think. So we can say yes if we are loading too objects in aseesion we
should go for Lazy Fetch strategy but in terms of time performance it does not provide any Benefit.
Agreed?
When a user has many addresses it is not efficient to load all of its addresses with it when they are not
needed. So in suchlike cases, you can declare that you want addresses to be loaded when they are
actually needed. This is called lazy loading.
EXAMPLE: UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
@Entity
@Table (name="USER_DETAIL")
public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
@ElementCollection(fetch=FetchType.LAZY)
@JoinTable(name="USER_ADDRESS", joinColumns=@JoinColumn(name="USER_ID"))
private Collection<Address> lisOfAddresses = new ArrayList<Address>();
public Collection<Address> getLisOfAddresses() {
return lisOfAddresses;
}
public void setLisOfAddresses(Collection<Address> lisOfAddresses) {
this.lisOfAddresses = lisOfAddresses;
}
public int getUserId() {

return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String toString()
{
return "[User Name: "+userName+"\n Office Address: "+lisOfAddresses+"]";
}
}

Now hibernate.cfg.xml and Address.java are same as the previous tutorial.

Now run the this with following class.

HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails(); // create user object
//user.setUserId(1);
user.setUserName("Dinesh Rajput");
Address address1 = new Address(); // create address object
address1.setStreet("First Street");
address1.setCity("First City");

address1.setState("First State");
address1.setPincode("First Pin");
Address address2 = new Address(); // create another address object
address2.setStreet("Second Street");
address2.setCity("Second City");
address2.setState("Second State");
address2.setPincode("Second Pin");
user.getLisOfAddresses().add(address1); // set the addresses objects to list of the addresses
user.getLisOfAddresses().add(address2);
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); // create session factory object
Session session = sessionFactory.openSession(); // create session object
session.beginTransaction(); // start transaction object
session.save(user); // save the user to database
session.getTransaction().commit(); // commit the transaction
session.close(); // closing session
session = sessionFactory.openSession(); // again create another session object
user = null;
user = (UserDetails) session.get(UserDetails.class, 1); // retrieved the user from the database for
particular user which user id = 2 this object it is proxy user object.
System.out.println(user.getLisOfAddresses().size());
}
}
******************************************************************************
OUTPUT:Look care fully the output has the two select query one is for user and another is for address
table when we callgetListOfAddresses();

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).


log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_DETAIL (USER_NAME) values (?)
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME,
STREET_NAME) values (?, ?, ?, ?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME,
STREET_NAME) values (?, ?, ?, ?, ?)
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_
from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=?
Hibernate: select lisofaddre0_.USER_ID as USER1_0_, lisofaddre0_.CITY_NAME as CITY2_0_,
lisofaddre0_.PIN_CODE as PIN3_0_, lisofaddre0_.STATE_NAME as STATE4_0_,
lisofaddre0_.STREET_NAME as STREET5_0_ from USER_ADDRESS lisofaddre0_ where
lisofaddre0_.USER_ID=?
2
******************************************************************************
Now if you change to some lines of code for this class file to verify the PROXY object.
Before calling getListOfAddresses() method close the session then look what happens.

session = sessionFactory.openSession(); // again create another session object


user = null;
user = (UserDetails) session.get(UserDetails.class, 1); // retrieved the user from the database for
particular user which user id = 2 this object it is proxy user object.
session.close(); // close the session before calling collection getter
System.out.println(user.getLisOfAddresses().size());
Now Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_DETAIL (USER_NAME) values (?)
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME,
STREET_NAME) values (?, ?, ?, ?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME,
STREET_NAME) values (?, ?, ?, ?, ?)
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_
from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=?
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a
collection of role: com.sdnext.hibernate.tutorial.dto.UserDetails.lisOfAddresses, no session or
session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException
(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected
(AbstractPersistentCollection.java:372)
at
org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119)
at org.hibernate.collection.PersistentBag.size(PersistentBag.java:248)
at com.sdnext.hibernate.tutorial.HibernateTestDemo.main(HibernateTestDemo.java:48)
******************************************************************************
As above code failed run because when we are using the LAZY Type strategy of fetching an object
hibernate session return the proxy object, it exist in the session if we are closing the session the lazy
loading is not happening.

2. Eager Fetch Strategy: In hibernate 2 this is default behavior of the to retrieving an object from the
database.
Eager/Join Fetch strategy:- Join Fetch strategy the eager fetching of associations.The purpose of Join
Fetch strategy is optimization in terms of time.I mean even associations are fetched right at the time of
fetching parent object. So in this case we dont make database call again and again . So this will be much
faster.Agreed that this will bad if we are fetching too many objects in a session because we can get java
heap error.

Now we look on the code for EAGER LOADING.


UserDetais.java
package com.sdnext.hibernate.tutorial.dto;
import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
@Entity
@Table (name="USER_DETAIL")
public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
@ElementCollection(fetch=FetchType.EAGER)
@JoinTable(name="USER_ADDRESS", joinColumns=@JoinColumn(name="USER_ID"))
private Collection<Address> lisOfAddresses = new ArrayList<Address>();
public Collection<Address> getLisOfAddresses() {
return lisOfAddresses;
}
public void setLisOfAddresses(Collection<Address> lisOfAddresses) {
this.lisOfAddresses = lisOfAddresses;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String toString()
{
return "[User Name: "+userName+"\n Office Address: "+lisOfAddresses+"]";

}
}

Now run the following code and see the output--package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails();
//user.setUserId(1);
user.setUserName("Dinesh Rajput");
Address address1 = new Address();
address1.setStreet("First Street");
address1.setCity("First City");
address1.setState("First State");
address1.setPincode("First Pin");
Address address2 = new Address();
address2.setStreet("Second Street");
address2.setCity("Second City");
address2.setState("Second State");
address2.setPincode("Second Pin");
user.getLisOfAddresses().add(address1);
user.getLisOfAddresses().add(address2);
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
session = sessionFactory.openSession();
user = null;

user = (UserDetails) session.get(UserDetails.class, 1);


session.close(); //closing the session before calling collection getter
System.out.println(user.getLisOfAddresses().size());
}
}

OUTPUT:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_DETAIL (USER_NAME) values (?)
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME,
STREET_NAME) values (?, ?, ?, ?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME,
STREET_NAME) values (?, ?, ?, ?, ?)
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as
USER2_0_0_, lisofaddre1_.USER_ID as USER1_2_, lisofaddre1_.CITY_NAME as CITY2_2_,
lisofaddre1_.PIN_CODE as PIN3_2_, lisofaddre1_.STATE_NAME as STATE4_2_,
lisofaddre1_.STREET_NAME as STREET5_2_ from USER_DETAIL userdetail0_ left outer join
USER_ADDRESS lisofaddre1_ on userdetail0_.USER_ID=lisofaddre1_.USER_ID where
userdetail0_.USER_ID=?
2******************************************************************************
See this is successfully run the code because we are using the EAGER fetching strategy so in this
strategy session return the original object with all field are initialized when load on the memory.
In the above output string look care fully there are only one select statement with join clause.

So now can we say in the hibernate session where we are not loading too many objects we should
go for Eager fetch as it will be much better in terms of time response(Any ways memory will be
reclaimed by garbage collector once we close the session).

Hibernate One-To-One Mapping Tutorial :


Chapter 17
In the previous chapter we learned about the entity class has the field of the value type object and also
has the collection of thevalue type objects.
Now we will learning what happens when an entity class has the field of the entity type object. Means
that one entity is inside the one entity known as One-2-One Mapping.

Hibernate Mapping One-to-One:In this example you will learn how to map one-to-one relationship
using Hibernate. Consider the following relationship between UserDetails and Vehicle entity.

According to the relationship each user should have a unique vehicle.

For that we will use the following annotation.


@OneToOne:
Target:

Fields (including property get methods)


Defines a single-valued association to another entity that has one-to-one multiplicity. It is not
normally necessary to specify the associated target entity explicitly since it can usually be inferred
from the type of the object being referenced. If the relationship is bidirectional, the non-owning
side must use the mappedBy element of the @OneToOne annotation to specify the relationship
field or property of the owning side.
The @OneToOne annotation may be used within an embeddable class to specify a relationship
from the embeddable class to an entity class.
Now we look the following Example related to the One to One mapping.
1. First Create Vehicle Class
Vehicle.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="VEHICLE")
public class Vehicle
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="VEHICLE_ID")
private int vehicleId;
@Column(name="VEHICLE_NAME")
private String vehicleName;
public int getVehicleId() {
return vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(String vehicleName) {
this.vehicleName = vehicleName;

}
}
2. Create the User Class
UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table (name="USER_DETAIL")
public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
@OneToOne
@JoinColumn(name="VEHICLE_ID")
private Vehicle vehicle;
public Vehicle getVehicle() {
return vehicle;
}
public void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {

this.userName = userName;
}
}

3. Create the hibernate configuration file.


hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>

<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>
<mapping class="com.sdnext.hibernate.tutorial.dto.Vehicle"/>
</session-factory>
</hibernate-configuration>

4. Create Test Demo class for run this code.


HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
import com.sdnext.hibernate.tutorial.dto.Vehicle;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails(); //create the user entity
Vehicle vehicle = new Vehicle(); //create the vehicle entity
vehicle.setVehicleName("BMW Car"); //set vehicle name
user.setUserName("Dinesh Rajput"); //set the user name
user.setVehicle(vehicle); //set the vehicle entity to the field of the user entity i.e. vehicle entity inside
the user entity
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); //create session factory object
Session session = sessionFactory.openSession(); //create the session object
session.beginTransaction();//create the transaction from the session object
session.save(vehicle); // save the vehicle entity to the database
session.save(user); // save the user entity to the database
session.getTransaction().commit(); //close the transaction
session.close(); //close the session
}
}
OUTPUT:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into VEHICLE (VEHICLE_NAME) values (?)
Hibernate: insert into USER (USER_NAME, VEHICLE_ID) values (?, ?)

Now we look the created tables for that.

One-To-Many Mapping in Hibernate : Chapter


18
In this chapter we will discuss about the One To Many Mapping. In previous we look that what is One To
One Mapping and also discussed some examples about that.
A one-to-many relationship occurs when one entity is related to many occurrences in another entity.

In this chapter you will learn how to map one-to-many relationship using Hibernate. Consider the following
relationship betweenUserDetails Class and Vehicle entity.

One user have the multiple vehicles.

Class diagram for that given below.

In this example UserDetails class has the collection of the another entity class Vehicle. So the given
below diagram so table structure for that.

For that we will use the following annotation.


@OneToMany:
Target:

Fields (including property get methods)


Defines a many-valued association with one-to-many multiplicity. If the collection is defined using
generics to specify the element type, the associated target entity type need not be specified;
otherwise the target entity class must be specified. If the relationship is bidirectional,
the mappedBy element must be used to specify the relationship field or property of the entity that
is the owner of the relationship.
The OneToMany annotation may be used within an embeddable class contained within an entity
class to specify a relationship to a collection of entities. If the relationship is bidirectional,
the mappedBy element must be used to specify the relationship field or property of the entity that
is the owner of the relationship.
Now we look the following Example related to the One to Many mapping.
1. First Create Vehicle Class
Vehicle.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="VEHICLE")
public class Vehicle
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="VEHICLE_ID")
private int vehicleId;
@Column(name="VEHICLE_NAME")
private String vehicleName;
public int getVehicleId() {
return vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(String vehicleName) {

this.vehicleName = vehicleName;
}
}
2. Create the User Class
UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table (name="USER")
public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
@OneToMany
@JoinTable( name="USER_VEHICLE",
joinColumns=@JoinColumn(name="USER_ID"),
inverseJoinColumns=@JoinColumn(name="VEHICLE_ID")) //its optional using for name
configuration of the join table
private Collection<Vehicle> vehicle = new ArrayList<Vehicle>();
public int getUserId() {
return userId;
}
public Collection<Vehicle> getVehicle() {
return vehicle;
}
public void setVehicle(Collection<Vehicle> vehicle) {
this.vehicle = vehicle;

}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}

3. Create the hibernate configuration file.


hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>

<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>
<mapping class="com.sdnext.hibernate.tutorial.dto.Vehicle"/>
</session-factory>
</hibernate-configuration>

4. Create Test Demo class for run this code.


HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import com.sdnext.hibernate.tutorial.dto.UserDetails;
import com.sdnext.hibernate.tutorial.dto.Vehicle;

public class HibernateTestDemo {


/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails(); //create the user entity object
Vehicle vehicle = new Vehicle(); //create the first vehicle entity object
Vehicle vehicle2 = new Vehicle(); //create the second vehicle entity
vehicle.setVehicleName("BMW Car"); //set the value to the vehicle entity
vehicle2.setVehicleName("AUDI Car");
user.setUserName("Dinesh Rajput"); //Set the value to the user entity
user.getVehicle().add(vehicle); //add vehicle to the list of the vehicle
user.getVehicle().add(vehicle2);

SessionFactory sessionFactory = new


AnnotationConfiguration().configure().buildSessionFactory(); //create session factory object
Session session = sessionFactory.openSession(); //create the session object
session.beginTransaction(); //start the transaction of the session object
session.save(vehicle); //saving the vehicle to the database
session.save(vehicle2);
session.save(user); //save the user to the database
session.getTransaction().commit(); //close the transaction
session.close(); //close the session
}
}
******************************************************************************
OUTPUT:
******************************************************************************
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into VEHICLES (VEHICLE_NAME) values (?)
Hibernate: insert into VEHICLES (VEHICLE_NAME) values (?)
Hibernate: insert into USER (USER_NAME) values (?)
Hibernate: insert into USER_VEHICLE (USER_ID, VEHICLE_ID) values (?, ?)
Hibernate: insert into USER_VEHICLE (USER_ID, VEHICLE_ID) values (?, ?)

Now we look the table structure about this example.

Now how can implement this mapping through mapping file( .hbm.xml) instead of the annotations.
For user class..
UserDetails.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.UserDetails" table="USER">
<id name="userId" type="long" column="ID" >
<generator class="assigned"/>
</id>
<property name="userName">
<column name="UserName" />
</property>
<list name="vehicle" table="STUDENT_VEHICLE" cascade="all">
<key column="USER_ID" />
<many-to-many column="VEHICLE_ID"
unique="true" class="com.sdnext.hibernate.tutorial.dto.Vehicle" />
</list>

</class>
</hibernate-mapping>

Mapping File For Vehicle Class...


vehicle.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.Vehicle" table="VEHICLE">
<id name="userId" type="long" column="ID" >
<generator class="assigned"/>
</id>
<property name="vehicleName" column="VEHICLE_NAME"> </property>
</class>
</hibernate-mapping>

So it is brief description about the One To Many Mapping with using annotation and also
using .hbm.xml files for entity class.

Many-To-One Mapping in Hibernate : Chapter


19
In this chapter we will discuss about the Many To One Relationship Mapping. In previous we look that
what is One To Many Mapping and also discussed some examples about that. Actually Many To One is
the reverse of the One To Many(USER has many Vehicles means one user related to the many vehicles
in reverse we can say that many vehicles related to the one user i.e. Many To One relationship mapping).

Many-to-One Relationships:
A many-to-one relationship is where one entity contains values that refer to another entity (a column or
set of columns) that has unique values. In relational databases, these many-to-one relationships are often
enforced by foreign key/primary key relationships, and the relationships typically are between fact and
dimension tables and between levels in a hierarchy.

In this example multiple vehicles (BMW Car, AUDI Car, Maruti Car and Mahindra etc.) are linked to the
same User (whose primary key is 1).

Class diagram for that is given below.

According to the relationship many vehicles can have the same owner.

To create this relationship you need to have a USER and VEHICLE table. The relational model is shown
below.

For that we will use the following annotation.


@ManyToOne :
Target:
Fields (including property get methods)
Defines a single-valued association to another entity class that has many-to-one multiplicity. It is
not normally necessary to specify the target entity explicitly since it can usually be inferred from
the type of the object being referenced. If the relationship is bidirectional, the nonowning OneToMany entity side must used the mappedBy element to specify the relationship field
or property of the entity that is the owner of the relationship.
The ManyToOne annotation may be used within an embeddable class to specify a relationship
from the embeddable class to an entity class. If the relationship is bidirectional, the nonowning OneToMany entity side must use the mappedByelement of the OneToMany annotation
to specify the relationship field or property of the embeddable field or property on the owning side
of the relationship. The dot (".") notation syntax must be used in the mappedBy element to
indicate the relationship attribute within the embedded attribute. The value of each identifier used
with the dot notation is the name of the respective embedded field or property.

Now we look the following Example related to the One to Many mapping.
UserDetails.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table (name="USER")
public class UserDetails
{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
public int getUserId() {
return userId;
}

public void setUserId(int userId) {


this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Vehicle.java
package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="VEHICLE")
public class Vehicle
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="VEHICLE_ID")
private int vehicleId;
@Column(name="VEHICLE_NAME")
private String vehicleName;
@ManyToOne
@JoinColumn(name ="USER_ID")
private UserDetails user;
public UserDetails getUser() {
return user;
}
public void setUser(UserDetails user) {
this.user = user;
}
public int getVehicleId() {
return vehicleId;
}

public void setVehicleId(int vehicleId) {


this.vehicleId = vehicleId;
}
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(String vehicleName) {
this.vehicleName = vehicleName;
}
}

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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>

<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/>

<mapping class="com.sdnext.hibernate.tutorial.dto.Vehicle"/>
</session-factory>
</hibernate-configuration>
HibernateTestDemo.java
package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
import com.sdnext.hibernate.tutorial.dto.Vehicle;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails(); //create an user entity
Vehicle vehicle = new Vehicle(); //create a vehicle entity
Vehicle vehicle2 = new Vehicle(); //create second vehicle entity
vehicle.setVehicleName("BMW Car"); //set BMW car
vehicle.setUser(user); //set user for that car
vehicle2.setVehicleName("AUDI Car"); //set second car Audi
vehicle2.setUser(user);//set user for that car
user.setUserName("Dinesh Rajput"); //set user property
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); //create the session factory object
Session session = sessionFactory.openSession(); //create the session object
session.beginTransaction(); //create the transaction object
session.save(vehicle);
session.save(vehicle2);
session.save(user);
session.getTransaction().commit();
session.close();
}
}
******************************************************************************
OUTPUT:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).

log4j:WARN Please initialize the log4j system properly.


Hibernate: insert into VEHICLE (USER_ID, VEHICLE_NAME) values (?, ?)
Hibernate: insert into VEHICLE (USER_ID, VEHICLE_NAME) values (?, ?)
Hibernate: insert into USER (USER_NAME) values (?)
Hibernate: update VEHICLE set USER_ID=?, VEHICLE_NAME=? where VEHICLE_ID=?
Hibernate: update VEHICLE set USER_ID=?, VEHICLE_NAME=? where VEHICLE_ID=?

Now we look the table structure about this example.

Now how can implement this mapping through mapping file( .hbm.xml) instead of the annotations.
For user class..
UserDetails.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.UserDetails" table="USER">
<id name="userId" type="long" column="ID" >
<generator class="assigned"/>
</id>

<property name="userName">
<column name="UserName" />
</property>
</class>
</hibernate-mapping>

Mapping File For Vehicle Class...


vehicle.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.Vehicle" table="VEHICLE">
<id name="userId" type="long" column="ID" >
<generator class="assigned"/>
</id>
<property name="vehicleName" column="VEHICLE_NAME"> </property>
<many-to-one name="userDetail" class="com.sdnext.hibernate.tutorial.dto.UserDetails"
column="USER_ID" cascade="all" not-null="true" />
</class>
</hibernate-mapping>

The many-to-one element is used to create the many-to-one relationship between the Vehicle and
UserDetail entities. The cascadeoption is used to cascade the required operations to the associated
entity. If the cascade option is set to all then all the operations will be cascaded. For instance when you
save a Vehicle object, the associated UserDetail object will also be saved automatically.

In Next Chapter we will discuss about the Many To Many Mapping.

Many-To-Many Mapping in Hibernate :


Chapter 20
Many-to-many relationships occur when each record in an entity may have many linked records in another entity
and vice-versa.
In this chapter you will learn how to map many-to-many relationship using Hibernate. Consider the
following relationship betweenVehicle and UserDetails entity.

According to the relationship a user can have in any number of vehicles and the vehicle can have any
number of users.
UserDetail.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.

<span style="color: #20124d;">package com.sdnext.hibernate.tutorial.dto;


import java.util.ArrayList;
import java.util.Collection;
import
import
import
import
import
import
import

javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.ManyToMany;
javax.persistence.Table;

<b>@Entity
@Table (name="USER")</b>
public class UserDetails
{
<b>@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)</b>
private int
userId;
<b>@Column(name="USER_NAME") </b>
private String userName;
<b>@ManyToMany</b>
private Collection<Vehicle> vehicle = new ArrayList<Vehicle>();
public int getUserId() {
return userId;
}
public Collection<Vehicle> getVehicle() {
return vehicle;
}
public void setVehicle(Collection<Vehicle> vehicle) {
this.vehicle = vehicle;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}

47.

}</span>

Vehicle.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.

<span style="color: #20124d;">package com.sdnext.hibernate.tutorial.dto;


import java.util.ArrayList;
import java.util.Collection;
import
import
import
import
import
import
import

<b>@Entity
@Table(name="VEHICLE")</b>
public class Vehicle
{<b>
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="VEHICLE_ID")</b>
private int vehicleId;
<b>@Column(name="VEHICLE_NAME")</b>
private String vehicleName;
<b>@ManyToMany(mappedBy="vehicle")</b>
private Collection<UserDetails> user = new ArrayList<UserDetails>();
public Collection<UserDetails> getUser() {
return user;
}
public void setUser(Collection<UserDetails> user) {
this.user = user;
}
public int getVehicleId() {
return vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(String vehicleName) {
this.vehicleName = vehicleName;
}
}</span>

hibernate.cfg.xml:
view plainprint?

javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.ManyToMany;
javax.persistence.Table;

1.
<hibernate-configuration>
2.
<session-factory>
3.
<!-- Database connection settings -->
4.
<property name="connection.driver_class">com.mysql.jdbc.Driver</propert
y>
5.
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB
</property>
6.
<property name="connection.username">root</property>
7.
<property name="connection.password">root</property>
8.
9.
<!-- JDBC connection pool (use the built-in) -->
10.
<property name="connection.pool_size">1</property>
11.
12.
<!-- SQL dialect -->
13.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
14.
15.
<!-- Enable Hibernate's automatic session context management -->
16.
<property name="current_session_context_class">thread</property>
17.
18.
<!-- Disable the second-level cache -->
19.
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvid
er</property>
20.
21.
<!-- Echo all executed SQL to stdout -->
22.
<property name="show_sql">true</property>
23.
24.
<!-- Drop and re-create the database schema on startup -->
25.
<property name="hbm2ddl.auto">create</property>
26.
27.
28.
<mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails">
29.
<mapping class="com.sdnext.hibernate.tutorial.dto.Vehicle">
30.
31.
</mapping></mapping></session-factory>
32.
</hibernate-configuration>

HibernateTestDemo.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

<span style="color: #20124d;"><b>package com.sdnext.hibernate.tutorial;


import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
import com.sdnext.hibernate.tutorial.dto.Vehicle;

public class HibernateTestDemo {


/**
* @param args
*/
public static void main(String[] args)
{
UserDetails user = new UserDetails();
UserDetails user2 = new UserDetails();
Vehicle vehicle = new Vehicle();

22.
Vehicle vehicle2 = new Vehicle();
23.
24.
vehicle.setVehicleName("Car");
25.
vehicle.getUser().add(user);
26.
vehicle.getUser().add(user2);
27.
28.
vehicle2.setVehicleName("Jeep");
29.
vehicle2.getUser().add(user2);
30.
vehicle2.getUser().add(user);
31.
32.
user.setUserName("First User");
33.
user2.setUserName("Second User");
34.
user.getVehicle().add(vehicle);
35.
user.getVehicle().add(vehicle2);
36.
user2.getVehicle().add(vehicle);
37.
user2.getVehicle().add(vehicle2);
38.
39.
SessionFactory sessionFactory = new AnnotationConfiguration().configure(
).buildSessionFactory();
40.
Session session = sessionFactory.openSession();
41.
session.beginTransaction();
42.
session.save(vehicle);
43.
session.save(vehicle2);
44.
session.save(user);
45.
session.save(user2);
46.
session.getTransaction().commit();
47.
session.close();
48.
}
49.
}</b></span>

Using Mapping files instead of Annotation


userDetail.hbm.xml
view plainprint?

1.
<hibernate-mapping>
2.
<class name="com.sdnext.hibernate.tutorial.dto.UserDetails" table="USER">
3.
<id column="ID" name="userId" type="long">
4.
<generator class="assigned">
5.
</generator></id>
6.
<property column="column" name="UserName">
7.
<list cascade="all" name="vehicle" table="USER_VEHICLE">
8.
<key column="USER_ID">
9.
<many-tomany class="com.sdnext.hibernate.tutorial.dto.Vehicle" column="VEHICLE_ID">
10.
</many-to-many></key></list>
11.
</property></class>
12.
</hibernate-mapping>

vehicle.hbm.xml
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.

<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.Vehicle" table="VEHICLE">
<id column="ID" name="userId" type="long">
<generator class="assigned">
</generator></id>
<property column="VEHICLE_NAME" name="vehicleName">
</property></class>
</hibernate-mapping>

CascadeTypes in Hibernate and Other Things


: Chapter 21
In this section, you will know about the jpa relationship. JPA supports the relationship between
entities.

JPA Relationship
In this section, you will know about the jpa relationship. JPA supports the relationship between entities.
There are following types of relationship:
1.
One-to-one
2.
One-to-many
3.
Many-to-one
4.
Many-to-many
JPA relationships are not bi-directional. JPA annotations are added to define the relationship. If, you want
to make a relationship bi-directional to use a special attribute.
1.
One-to-one: A OneToOne relation mapping to a single-value association to another
entity. It has one-to-one multiplicity and infers the associated target entity from the type of the
object being referenced.
Use of the @OneToOne Annotation:
1.
Configure the fetch type to LAZY
2.
Configure the mapping to forbid null values (for non-primitive types) in case null
values are inappropriate for your application
3.
Configure the associated target entity if it cannot be inferred from the type of the
object being referenced
4.
Configure the operations that must be cascaded to the target of the association.
For example, if the owning entity is removed, ensure that the target of the association is
also removed
2.
One-to-many: JPA defines a OneToMany mapping for a many-valued association with
one-to-many multiplicity.
Use of the @OneToMany Annotation:
1.
Configure the fetch type to EAGER
2.
Configure the associated target entity because the Collection used is not defined
using generics
3.
Configure the operations that must be cascaded to the target of the association:
for example, if the owning entity is removed, ensure that the target of the association is
also removed
4.
Configure the details of the join table used by TopLink JPA for uni-directional
one-to-many relationships
3.
Many-to-one: JPA defines a ManyToOne mapping for a single-valued association to
another entity class that has many-to-one multiplicity.
Use the @ManyToOne Annotation to:
1.
Configure the fetch type to LAZY
2.
Configure the mapping to forbid null values (for non-primitive types) in case null
values are inappropriate for your application

3.
Configure the associated target entity if it cannot be inferred from the type of the
object being referenced
4.
Configure the operations that must be cascaded to the target of the association:
for example, if the owning entity is removed, ensure that the target of the association is
also removed
4.
Many-to-many: JPA defines a @ManyToMany mapping for a many-valued association
with many-to-many multiplicity.
Use of the @ManyToMany annotation:
1.
Declare the cardinality of the relationship
2.
Configure the fetch type to EAGER
3.
Configure the mapping to forbid null values (for non-primitive types) in case null
values are inappropriate for your application
4.
Configure the associated target entity because the Collection used is not defined
using generics
5.
Configure the operations that must be cascaded to the target of the association;
for example, if the owning entity is removed, ensure that the target of the association is
also removed
There are following types of cascade:
6.
CascadeType.PERSIST: When we persist and entity all the entities held in this
field persist too. If you want to persist an entity and the fields dont use it fails.
7.
CascadeType.REMOVE: When we delete an entity all the entities held in this
field delete too.
8.
CascadeType.REFRESH: When we refresh an entity all the entities held in this
field refresh too.
9.
CascadeType.MERGE: When we merde an entity all the entities held in this flied
merged too
The property cascade = CascadeType.ALL indicates that when we persist, remove, refresh or merge
this entity all the entities held in this field would be persist, remove, delete or update.

Implementing Inheritance in Hibernate (Single


Table Strategy, With Table Per Class Strategy,
With Joined Strategy) : Chapter 22
This tutorial discusses what are the types of inheritance models in Hibernate and describes how they
work like vertical inheritance and horizontal.
There are three types of inheritance mapping in hibernate
1. Table per concrete class with unions
2. Table per class hierarchy(Single Table Strategy)
3. Table per subclass
Example:
Let us take the simple example of 3 java classes.
Class TwoWheelerVehicle and FourWheelerVehicle are inherited from Vehicle Abstract class.

1. Table per concrete class with unions


In this case there will be 2 tables
Tables: TwoWheelerVehicle, FourWheelerVehicle[all common attributes will be duplicated]
2. Table per class hierarchy
Single Table can be mapped to a class hierarchy
There will be only one table in database called 'Vehicle' that will represent all the attributes required for all 3
classes.
But it needs some discriminating column to differentiate between TwoWheelerVehicle and FourWheelerVehicle;
3. Table per subclass
In this case there will be 3 tables represent TwoWheelerVehicle , FourWheelerVehicle and Vehicle

Inheritance is one of the most visible facets of Object-relational mismatch. Object oriented systems can model
both is a and has a relationship. Relational model supports only has a relationship between two entities.
Hibernate can help you map such Objects with relational tables. But you need to choose certain mapping strategy
based on your needs. There are three possible strategies to use.

1.
2.

Single Table Strategy,


With Table Per Class Strategy,

3.

With Joined Strategy

Single Table Strategy


In Single table per subclass, the union of all the properties from the inheritance hierarchy is mapped to
one table. As all the data goes in one table, a discriminator is used to differentiate between different type
of data.
Advantages of Single Table per class hierarchy

Simplest to implement.

Only one table to deal with.

Performance wise better than all strategies because no joins or sub-selects need to be
performed.
Disadvantages:

Most of the column of table are nullable so the NOT NULL constraint cannot be applied.

Tables are not normalized.


Lets see the following example code.
Vehicle.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
gy
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.

package com.sdnext.hibernate.tutorial.dto;
import
import
import
import
import
import
import
import

javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.Inheritance;
javax.persistence.InheritanceType;
javax.persistence.Table;

@Entity
@Table(name="VEHICLE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) //Least normalisation strate
public class Vehicle
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="VEHICLE_ID")
private int vehicleId;
@Column(name="VEHICLE_NAME")
private String vehicleName;
public int getVehicleId() {
return vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getVehicleName() {
return vehicleName;
}

34.
35.
36.
37.

public void setVehicleName(String vehicleName) {


this.vehicleName = vehicleName;
}
}

TwoWheeler.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.

package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="TWO_WHEELER")
//@DiscriminatorValue("Bike")
public class TwoWheeler extends Vehicle
{
@Column(name="STEERING_TYPE")
private String steeringTwoWheeler;
public String getSteeringTwoWheeler()
{
return steeringTwoWheeler;
}
public void setSteeringTwoWheeler(String steeringTwoWheeler)
{
this.steeringTwoWheeler = steeringTwoWheeler;
}
}

FourWheeler.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.

package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="FOUR_WHEELER")
//@DiscriminatorValue("Car")
public class FourWheeler extends Vehicle
{
@Column(name="STEERING_TYPE")
private String steeringFourWheeler;
public String getSteeringFourWheeler()
{
return steeringFourWheeler;
}
public void setSteeringFourWheeler(String steeringFourWheeler)
{
this.steeringFourWheeler = steeringFourWheeler;

23.
24.

}
}

hibernate.cfg.xml
view plainprint?

1.
<hibernate-configuration>
2.
<session-factory>
3.
<!-- Database connection settings -->
4.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
5.
<property name="connection.url">jdbc:mysql://localhost:3306/vehicleDB2</prope
rty>
6.
<property name="connection.username">root</property>
7.
<property name="connection.password">root</property>
8.
9.
<!-- JDBC connection pool (use the built-in) -->
10.
<property name="connection.pool_size">1</property>
11.
12.
<!-- SQL dialect -->
13.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
14.
15.
<!-- Enable Hibernate's automatic session context management -->
16.
<property name="current_session_context_class">thread</property>
17.
18.
<!-- Disable the second-level cache -->
19.
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</pr
operty>
20.
21.
<!-- Echo all executed SQL to stdout -->
22.
<property name="show_sql">true</property>
23.
24.
<!-- Drop and re-create the database schema on startup -->
25.
<property name="hbm2ddl.auto">create</property>
26.
27.
28.
<mapping class="com.sdnext.hibernate.tutorial.dto.Vehicle">
29.
<mapping class="com.sdnext.hibernate.tutorial.dto.TwoWheeler">
30.
<mapping class="com.sdnext.hibernate.tutorial.dto.FourWheeler">
31.
32.
</mapping></mapping></mapping></session-factory>
33.
</hibernate-configuration>

Now run the following test class


HibernateTestDemo.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.

package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.FourWheeler;
import com.sdnext.hibernate.tutorial.dto.TwoWheeler;
import com.sdnext.hibernate.tutorial.dto.Vehicle;
public class HibernateTestDemo {
/**

14.
* @param args
15.
*/
16.
public static void main(String[] args)
17.
{
18.
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buil
dSessionFactory();
19.
Session session = sessionFactory.openSession();
20.
session.beginTransaction();
21.
22.
Vehicle vehicle = new Vehicle();
23.
vehicle.setVehicleName("Car");
24.
25.
TwoWheeler twoWheeler = new TwoWheeler();
26.
twoWheeler.setVehicleName("Bike");
27.
twoWheeler.setSteeringTwoWheeler("Bike Steering Handle");
28.
29.
FourWheeler fourWheeler = new FourWheeler();
30.
fourWheeler.setVehicleName("Alto");
31.
fourWheeler.setSteeringFourWheeler("Alto Steering Wheel");
32.
33.
session.save(vehicle);
34.
session.save(twoWheeler);
35.
session.save(fourWheeler);
36.
37.
session.getTransaction().commit();
38.
session.close();
39.
}
40.
}

In the above table Vehicle there are four columns (DTYPE, VEHICLE_ID, VEHICLE_NAME,
STEERING_TYPE).
The first column has the value of discriminator type(DTYPE) is Vehicle, TwoWheeler, FourWheeler as
its entity name by default.
For user convenience we can override the default value of column as well as column name by using the
following annotation.

@DiscriminatorColumn
Target:
Classes
Specifies the discriminator column for the SINGLE_TABLE and JOINED Inheritance mapping strategies.
The strategy and the discriminator column are only specified in the root of an entity class hierarchy or
subhierarchy in which a different inheritance strategy is applied
If the DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the
discriminator column defaults to "DTYPE" and the discriminator type to DiscriminatorType.STRING.
@DiscriminatorValue
Target:
Classes
Specifies the value of the discriminator column for entities of the given type.
The DiscriminatorValue annotation can only be specified on a concrete entity class.
If the DiscriminatorValue annotation is not specified and a discriminator column is used, a providerspecific function will be used to generate a value representing the entity type. If the DiscriminatorType is
STRING, the discriminator value default is the entity name.
The inheritance strategy and the discriminator column are only specified in the root of an entity class
hierarchy or subhierarchy in which a different inheritance strategy is applied. The discriminator value, if
not defaulted, should be specified for each entity class in the hierarchy.
@Inheritance
Target:
Classes
Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class
that is the root of the entity class hierarchy. If the Inheritance annotation is not specified or if no
inheritance type is specified for an entity class hierarchy, the SINGLE_TABLE mapping strategy is used.
Now adding the following annotation to the Vehicle class is
view plainprint?

1.
2.
3.
gy
4.
5.
6.
7.
8.
9.

@Entity
@Table(name="VEHICLE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) //Least normalisation strate
@DiscriminatorColumn(
name="VEHICLE_TYPE",
discriminatorType=DiscriminatorType.STRING
)
public class Vehicle
{

Now adding following annotation to the TwoWheeler class


view plainprint?

1.
2.
3.

@DiscriminatorValue("Bike")
public class TwoWheeler extends Vehicle
{

Now adding following annotation to the FourWheeler class


view plainprint?

1.
2.
3.

@DiscriminatorValue("Car")
public class FourWheeler extends Vehicle
{

After these above modification we run the code then we will get the following output.

With Table Per Class Strategy


In this case every entity class has its own table i.e. table per class. The data for Vehicle is duplicated in
both the tables.
This strategy is not popular and also have been made optional in Java Persistence API.
Advantage:

Possible to define NOT NULL constraints on the table.

Disadvantage:

Tables are not normalized.

To support polymorphism either container has to do multiple trips to database or use SQL UNION
kind of feature.
In this case there no need for the discriminator column because all entity has own table.
The Vehicle entity in this case is
Vehicle.java
view plainprint?

1.
2.
3.
4.
5.

package com.sdnext.hibernate.tutorial.dto;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;

6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
d
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.

import
import
import
import
import
import
import

javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.Inheritance;
javax.persistence.InheritanceType;
javax.persistence.Table;

@Entity
@Table(name="VEHICLE")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) //slightly more normalize
public class Vehicle
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="VEHICLE_ID")
private int vehicleId;
@Column(name="VEHICLE_NAME")
private String vehicleName;
public int getVehicleId() {
return vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(String vehicleName) {
this.vehicleName = vehicleName;
}
}

And there no need to the discriminator value for the TwoWheeler and FourWheeler Entity so in this case
the
TwoWheeler.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.

package com.sdnext.hibernate.tutorial.dto;
import
import
import
import

javax.persistence.Column;
javax.persistence.DiscriminatorValue;
javax.persistence.Entity;
javax.persistence.Table;

@Entity
@Table(name="TWO_WHEELER")
public class TwoWheeler extends Vehicle
{
@Column(name="STEERING_TYPE")
private String steeringTwoWheeler;
public String getSteeringTwoWheeler()
{
return steeringTwoWheeler;
}
public void setSteeringTwoWheeler(String steeringTwoWheeler)

21.
22.
23.
24.

{
this.steeringTwoWheeler = steeringTwoWheeler;
}
}

FourWheeler.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.

package com.sdnext.hibernate.tutorial.dto;
import
import
import
import

javax.persistence.Column;
javax.persistence.DiscriminatorValue;
javax.persistence.Entity;
javax.persistence.Table;

@Entity
@Table(name="FOUR_WHEELER")
public class FourWheeler extends Vehicle
{
@Column(name="STEERING_TYPE")
private String steeringFourWheeler;
public String getSteeringFourWheeler()
{
return steeringFourWheeler;
}
public void setSteeringFourWheeler(String steeringFourWheeler)
{
this.steeringFourWheeler = steeringFourWheeler;
}
}

With Joined Strategy


It's highly normalized but performance is not good.
Advantage:

Tables are normalized.

Able to define NOT NULL constraint.


Disadvantage:

Does not perform as well as SINGLE_TABLE strategy


Using Join Strategy with the vehicle entity
Vehicle.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.

package com.sdnext.hibernate.tutorial.dto;
import
import
import
import
import
import
import
import
import
import

javax.persistence.Column;
javax.persistence.DiscriminatorColumn;
javax.persistence.DiscriminatorType;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.Inheritance;
javax.persistence.InheritanceType;
javax.persistence.Table;

@Entity
@Table(name="VEHICLE")
@Inheritance(strategy=InheritanceType.JOINED)//Highly normalized
public class Vehicle
{
@Id
@GeneratedValue
@Column(name="VEHICLE_ID")
private int vehicleId;
@Column(name="VEHICLE_NAME")
private String vehicleName;
public int getVehicleId() {
return vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(String vehicleName) {
this.vehicleName = vehicleName;
}
}

Now run the code we will get the following output.

We have seen the three strategies about inheritance in the hibernate.


A comparison of three strategies is as follows:

Criteria

Single Table

Table per subclass(Join Strategy)

Data not
normalized.

Constraint for
Normalized.
mandatory columns to be
Table Support not nullable cannot

Mandatory column constraint


applied.
can be applied

Change in any
subclass leads to change
in structure of Table
Discriminator
Present
Column

Retrieving
data

simple SELECT. All data is


in one table. Using
discriminator type,
individual types can be
selected

Absent

Table per Class

One table for


each concrete class.

Not
maintainable.

Change in
base class leads to
changes in all tables
of derived class
Absent

Joins among table. For example


fetching FourWheeler will require a
Separate Select or
join on FourWheeler and Vehicle table.
Union Select
If all user needs to be fetched than it
will put a join for all three tables

Multiple. For Vehicle type one insert


Updating and
Single INSERT or UPDATE on Vehicle table. For FourWheeler
Inserting
type one insert on Vehicle table and

One insert or update


for each subclass

another on FourWheeler table.


JPA Support

Mandatory

Optional

CRUD Operations Using Hibernate 3


(Annotation and Configuration) : Chapter 23
In this section, you will learn how to develop a CRUD application using hibernate annotation.
Follows the following steps for developing the CRUD application in hibernate annotation.
Step 1: Create Domain Entity Class
Student.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.

package com.sdnext.hibernate.tutorial.dto;
import java.io.Serializable;
import
import
import
import

javax.persistence.Column;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;

@Entity
@Table(name="STUDENT")
public class Student implements Serializable
{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 8633415090390966715L;
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="STUDENT_NAME")
private String studentName;
@Column(name="ROLL_NUMBER")
private int rollNumber;
@Column(name="COURSE")
private String course;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getRollNumber() {
return rollNumber;

43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.

}
public void setRollNumber(int rollNumber) {
this.rollNumber = rollNumber;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
}

Step 2: Create Hibernate Configuration file


hibernate.cfg.xml
file contains
(a.) database connection setting (database driver (com.mysql.jdbc.Driver), url
(jdbc:mysql://localhost:3306/hibernateDB2), username (root) and password (root)),
(b.) SQL dialect (dialect - org.hibernate.dialect.MySQLDialect),
(c.) enable hibernate's automatic session context management (current_session_context_class thread),
(d.) disable the second level cache (cache.provider_class - org.hibernate.cache.NoCacheProvider),
(e.) print all executed SQL to stdout (show_sql - true) and
(f.) drop and re-create the database schema on startup (hbm2ddl.auto - none).
view plainprint?

1.
<hibernate-configuration>
2.
<session-factory>
3.
<!-- Database connection settings -->
4.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
5.
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB2</pro
perty>
6.
<property name="connection.username">root</property>
7.
<property name="connection.password">root</property>
8.
9.
<!-- JDBC connection pool (use the built-in) -->
10.
<property name="connection.pool_size">1</property>
11.
12.
<!-- SQL dialect -->
13.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
14.
15.
<!-- Enable Hibernate's automatic session context management -->
16.
<property name="current_session_context_class">thread</property>
17.
18.
<!-- Disable the second-level cache -->
19.
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</pr
operty>
20.
21.
<!-- Echo all executed SQL to stdout -->
22.
<property name="show_sql">true</property>
23.
24.
<!-- Drop and re-create the database schema on startup -->
25.
<property name="hbm2ddl.auto">update</property>
26.
27.
<mapping class="com.sdnext.hibernate.tutorial.dto.Student">
28.
29.
</mapping></session-factory>
30.
</hibernate-configuration>

Step 3: Create Hibernate Utility Class


HibernateUtil.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
y();
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.

package com.sdnext.hibernate.tutorial.utility;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
public class HibernateUtil
{
private static final SessionFactory sessionFactory;
static
{
try
{
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactor
}
catch(Throwable th){
System.err.println("Enitial SessionFactory creation failed"+th);
throw new ExceptionInInitializerError(th);
}
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}

Step 4: Create Student on the database.


CreateStudent.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.

package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.sdnext.hibernate.tutorial.dto.Student;
import com.sdnext.hibernate.tutorial.utility.HibernateUtil;
public class CreateStudent {
/**
* @param args
*/
public static void main(String[] args)
{
//Create student entity object
Student student = new Student();
student.setStudentName("Dinesh Rajput");
student.setRollNumber(01);
student.setCourse("MCA");
//Create session factory object
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
//getting session object from session factory
Session session = sessionFactory.openSession();
//getting transaction object from session object
session.beginTransaction();
session.save(student);
System.out.println("Inserted Successfully");

31.
32.
33.
34.
35.

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

OUTPUT:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Inserted Successfully

Now the following code the reading the student data from database.
Step 5: Reading the Student data from the database table STUDENT
ReadStudent.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.

package com.sdnext.hibernate.tutorial;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.sdnext.hibernate.tutorial.dto.Student;
import com.sdnext.hibernate.tutorial.utility.HibernateUtil;
public class ReadStudent {
/**
* @param args
*/
public static void main(String[] args)
{
//Create session factory object
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
//getting session object from session factory
Session session = sessionFactory.openSession();
//getting transaction object from session object
session.beginTransaction();
Query query = session.createQuery("from Student");
List<student> students = query.list();

27.
for(Student student : students)
28.
{
29.
System.out.println("Roll Number: "+student.getRollNumber()+", Student Name: "+st
udent.getStudentName()+", Course: "+student.getCourse());
30.
}
31.
session.getTransaction().commit();
32.
sessionFactory.close();
33.
}
34.
}
35.
</student>

Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select student0_.ID as ID0_, student0_.COURSE as COURSE0_, student0_.ROLL_NUMBER
as ROLL3_0_, student0_.STUDENT_NAME as STUDENT4_0_ from STUDENT student0_
Roll Number: 1, Student Name: Dinesh Rajput, Course: MCA
Roll Number: 2, Student Name: Anamika Rajput, Course: PGDCP
Roll Number: 3, Student Name: Adesh Rajput, Course: MA
Roll Number: 4, Student Name: Vinesh Rajput, Course: BA

The following code is for updating the data into the database table "STUDENT".
Step 6: Update the Student Record in the Database.
UpdateStudent.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.

package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.sdnext.hibernate.tutorial.dto.Student;
import com.sdnext.hibernate.tutorial.utility.HibernateUtil;
public class UpdateStudent {
/**
* @param args
*/
public static void main(String[] args)
{
//Create session factory object
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
//getting session object from session factory
Session session = sessionFactory.openSession();
//getting transaction object from session object
session.beginTransaction();
Student student = (Student)session.get(Student.class, 2);
student.setStudentName("Sweety Rajput");

25.
26.
27.
28.
29.

System.out.println("Updated Successfully");
session.getTransaction().commit();
sessionFactory.close();
}
}

Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select student0_.ID as ID0_0_, student0_.COURSE as COURSE0_0_,
student0_.ROLL_NUMBER as ROLL3_0_0_, student0_.STUDENT_NAME as STUDENT4_0_0_ from
STUDENT student0_ where student0_.ID=?
Hibernate: update STUDENT set COURSE=?, ROLL_NUMBER=?, STUDENT_NAME=? where ID=?
Updated Successfully

Step 7: Delete the student data from the database.


DeleteStudent.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.sdnext.hibernate.tutorial.dto.Student;
import com.sdnext.hibernate.tutorial.utility.HibernateUtil;
public class DeleteStudent {
/**
* @param args
*/
public static void main(String[] args)
{
//Create session factory object
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
//getting session object from session factory
Session session = sessionFactory.openSession();
//getting transaction object from session object
session.beginTransaction();

22.
23.
24.
25.
26.
27.
28.

Student student = (Student)session.load(Student.class, 4);


session.delete(student);
System.out.println("Deleted Successfully");
session.getTransaction().commit();
sessionFactory.close();
}
}

Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select student0_.ID as ID0_0_, student0_.COURSE as COURSE0_0_,
student0_.ROLL_NUMBER as ROLL3_0_0_, student0_.STUDENT_NAME as STUDENT4_0_0_ from
STUDENT student0_ where student0_.ID=?
Deleted Successfully
Hibernate: delete from STUDENT where ID=?

Transient, Persistent and Detached Objects in


Hibernate : Chapter 24
In couple of previous chapters we have seen that every entity object are passed to three states of the
object before saving and updating the row in the database table as per as given in the following picture.

1. Transient State:
A New instance of a persistent class which is not associated with a Session, has no representation in
the database and no identifier value is considered transient by Hibernate:
view plainprint?

1.
2.

UserDetail user = new UserDetail();


user.setUserName("Dinesh Rajput");

3.

// user is in a transient state

2. Persistent State:
A persistent instance has a representation in the database , an identifier value and is associated with
a Session. You can make a transient instance persistent by associating it with a Session:
view plainprint?

1.
2.

Long id = (Long) session.save(user);


// user is now in a persistent state

3. Detached State:
Now, if we close the Hibernate Session, the persistent instance will become a detached instance: it
isn't attached to aSession anymore (but can still be modified and reattached to a new Session later
though).
view plainprint?

1.
2.

session.close();
//user in detached state

Difference between Transient and Detached States:


Transient objects do not have association with the databases and session objects. They are simple
objects and not persisted to the database. Once the last reference is lost, that means the object itself is
lost. And of course , garbage collected. The commits and rollbacks will have no effects on these objects.
They can become into persistent objects through the save method calls of Session object.
The detached object have corresponding entries in the database. These are persistent and not connected
to the Session object. These objects have the synchronized data with the database when the session was
closed. Since then, the change may be done in the database which makes this object stale. The detached
object can be reattached after certain time to another object in order to become persistent again.
Lets see in the following example to save or update the user data...
view plainprint?

1.
package com.sdnext.hibernate.tutorial;
2.
3.
import org.hibernate.Session;
4.
import org.hibernate.SessionFactory;
5.
import org.hibernate.cfg.AnnotationConfiguration;
6.
7.
import com.sdnext.hibernate.tutorial.dto.UserDetails;
8.
9.
public class HibernateTestDemo {
10.
/**
11.
* @param args
12.
*/
13.
public static void main(String[] args)
14.
{
15.
UserDetails userDetails = new UserDetails();
16.
userDetails.setUserName("Dinesh Rajput");
17.
userDetails.setAddress("Noida City");
18.
//Here 'userDetails' is TRANSIENT object
19.
20.
SessionFactory sessionFactory = new AnnotationConfiguration().co
nfigure().buildSessionFactory();
21.
Session session = sessionFactory.openSession();
22.
session.beginTransaction();
23.
24.
session.save(userDetails);
25.
//Here 'userDetails' is PERSISTENT object
26.
userDetails.setUserName("User Updated after session close");
27.
28.
session.getTransaction().commit();

29.
30.
31.
32.

session.close();
//Here 'userDetails' is DETACHED object
}
}

State Changes of Object in Hibernate :


Chapter 25
In the previous tutorial you learned about the three states of the entity object using by the Hibernate API.
1.
Transient State
2.
Persistent State
3.
Detached State
Now you will learn how to flow of object in these states and how to manage by the hibernate.Look in the
following figures-

1. When Creating a new Entity Object

Here we see when create an object it is in transient state in this state hibernate does not ask for save
this object means that in this state hibernate's session does not associate with that object in this state.
Once we calling session's save method now object move to the persistent state i.e. hibernate's session
associated with that object in this state if any change made in the object hibernate ask to the database
and made change in the database also.
After done our required events when we calling session's close method then object moves in
the detached state.

2. When Reading an Entity Object

Here we see that we are not getting new object from new operator, we get the object from session's get
method. Here we pass a primary key in the get method and getting a persistent object.

3. When Delete an Entity Object

Here after getting persistent object from session of hibernate. When we are calling the delete method of
the session object moves from persistent state to the transient state. If we calling the close method of the
session then that object moves to the detached state. If once object move to the transient state it never
become a persistent object.
Now we look the states diagram of the entity object in the following.

When object in the session area then it is in Persistent State.


When object before the session area then it is in Transient State.
When object after the session area then it is in Detached State.

Detached to Persistent State:

Lets see in the following example how to an object moves from detached state to the persistent state
again.
HibernateTestDemo.java
view plainprint?

1.
2.
3.
4.
5.

package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

6.
7.
import com.sdnext.hibernate.tutorial.dto.UserDetails;
8.
9.
public class HibernateTestDemo {
10.
11.
/**
12.
* @param args
13.
*/
14.
public static void main(String[] args)
15.
{
16.
UserDetails userDetails = new UserDetails();
17.
//Here 'userDetails' is in TRANSIENT state
18.
19.
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buil
dSessionFactory();
20.
Session session = sessionFactory.openSession();
21.
session.beginTransaction();
22.
23.
userDetails = (UserDetails) session.get(UserDetails.class, 1);
24.
//Here 'userDetails' is in PERSISTENT state
25.
26.
session.save(userDetails);
27.
session.getTransaction().commit();
28.
session.close();
29.
30.
session = sessionFactory.openSession();
31.
session.beginTransaction();
32.
33.
userDetails.setUserName("User Updated after session close");
34.
//Here 'userDetails' is in DETACHED state
35.
36.
session.update(userDetails);
37.
//Here 'userDetails' is again in PERSISTENT state
38.
session.getTransaction().commit();
39.
session.close();
40.
}
41.
}

Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.ADDRESS as ADDRESS0_0_,
userdetail0_.USER_NAME as USER3_0_0_ from User_Details userdetail0_ where
userdetail0_.USER_ID=?
Hibernate: select userdetail_.USER_ID, userdetail_.ADDRESS as ADDRESS0_,
userdetail_.USER_NAME as USER3_0_ from User_Details userdetail_ where userdetail_.USER_ID=?
Hibernate: update User_Details set ADDRESS=?, USER_NAME=? where USER_ID=?

Introducing HQL(Hibernate Query Language)


and the Query Object : Chapter 26
Hibernate created a new language named Hibernate Query Language (HQL), the syntax is quite similar
to database SQL language. The main difference between is HQL uses class name instead of table
name, and property names instead of column name.
Hibernate uses the following ways to retrieve objects from the database:

Hibernate Query Language (HQL)

Query By Criteria (QBC) and Query BY Example (QBE) using Criteria API

Native SQL queries


The most preferred way is using the Hibernate Query Language (HQL), which is an easy-to-learn and
powerful query language, designed as a minimal object-oriented extension to SQL. HQL has syntax and
keywords/clauses very similar to SQL. It also supports many other SQL-like features, such as aggregate
functions (for example: sum(), max()) and clauses such as group byand order by clause.

Why WE USE HQL?


Although it is possible to use native SQL queries directly with a Hibernate-based persistence layer, it is
more efficient to use HQL instead. The reasons of choosing HQL over the other two methods are given
below.

HQL allows representing SQL queries in object-oriented termsby using objects and properties
of objects.

Instead of returning plain data, HQL queries return the query result(s) in the form of
object(s)/tuples of object(s) that are ready to be accessed, operated upon, and manipulated
programmatically. This approach does away with the routine task of creating and populating objects from
scratch with the "resultset" retrieved from database queried.

HQL fully supports polymorphic queries. That is, along with the object to be returned as a query
result, all child objects (objects of subclasses) of the given object shall be returned.

HQL is easy to learn and implement, as its syntax and features are very similar to SQL.

HQL contains many advance features such as pagination, fetch join with dynamic profiling, and
so forth, as compared to SQL.

HQL facilitates writing database-type independent queries that are converted to the native SQL
dialect of the underlying database at runtime. This approach helps tap the extra features the native SQL
query provides, without using a non-standard native SQL query.

HQL Syntax>>
As described earlier, most of HQL's syntax and features are very similar to SQL. An HQL query may
consist of following elements:

Clauses

Aggregate functions

Subqueries
Clauses in the HQL are:

from

select

where

order by

group by
Aggregate functions are:

avg(...), sum(...), min(...), max(...)

count(*)

count(...), count(distinct ...), count(all...)


Subqueries
Subqueries are nothing but its a query within another query. Hibernate supports Subqueries if the
underlying database supports it.

Table A: HQL Clauses with their description, syntax, and examples.

Claus Description
e

Syntax

from The simplest form of an


HQL query. Specifies the
object whose instances
are to be returned as the
query result. Commonly
used with
the selectclause.

from object [as object_alias]* object_alias


from UserDetails as
simply means another name given to refer to user
an object for convenience.
Will return all
instances of
object UserDetails.

selec Specifies objects and


properties to be returned
t
in the query result set.
Used in conjunction with
the fromclause.

select [object.]property

wher Specifies the conditions


where condition
that should be satisfied by
e
the instances returned as Here, condition is a combination of logical,
the query result. Used
relational operators i.e. =, >, AND, NOT etc.
with select and/or from cl
ause.

Example

select user.userName
from UserDetails as
user
Will return all values
of userName in all
instances
ofUserDetails.
from UserDetails as
user where
user.userId > 2
Will return all
instances of user in
UserDetails whose
correspondinguser.us
erId values are
greater than 2.

order Specifies the order


(ascending/descending) in
by
which the properties of
objects returned as query
results should be listed.
Used with
the select and fromclause
s.

order
from UserDetails as
by object0.property0[asc|desc][, object1.prop user order by userId
erty0]...
asc
By default, order is ascending unless specified Will return a list of all
instances of user in
otherwise.
ascending order of
corresponding userId
values.

grou Specifies the grouping


group
p by criteria using objects
by object0.property0[,object1.property0]...
properties, by which the
list of objects returned as
a query result should be
grouped together. Used
with
the select and/or from cla
use.

select userId from


UserDetails as user
group by user.userId
Will return list of all
userId instances from
user grouped by
corresponding values
of user.

Select and Pagination in HQL : Chapter 27


Pagination of search results is a common requirement for any application.
Out of performance reasons it is recommended to restrict the number of returned objects per query. In
fact is a very common use case anyway that the user navigates from one page to an other. The way to
define pagination is exactly the way you would define pagination in a plain HQL or Criteria query.
Using the createQuery() method of a Session object that returns a Query object.
First, instantiate the Session object using the openSession() method of SessionFactory.
Then, invoke the createQuery() method on the resulting object.
Query q = session.createQuery("...");
q.setFirstResult(start);
q.setMaxResults(length);
Student.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

package com.sdnext.hibernate.tutorial.dto;
import java.io.Serializable;
import
import
import
import
import
import

javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.Table;

11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.

@Entity
@Table(name="STUDENT")
public class Student implements Serializable
{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 8633415090390966715L;
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="STUDENT_NAME")
private String studentName;
@Column(name="ROLL_NUMBER")
private int rollNumber;
@Column(name="COURSE")
private String course;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getRollNumber() {
return rollNumber;
}
public void setRollNumber(int rollNumber) {
this.rollNumber = rollNumber;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public String toString()
{
return "ROLL Number: "+rollNumber+"| Name: "+studentName+"| Course: "+course;

57.
58.

}
}

hibernate.cfg.xml
view plainprint?

1.
<hibernate-configuration>
2.
<session-factory>
3.
<!-- Database connection settings -->
4.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
5.
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB2</pro
perty>
6.
<property name="connection.username">root</property>
7.
<property name="connection.password">root</property>
8.

9.
<!-- JDBC connection pool (use the built-in) -->
10.
<property name="connection.pool_size">1</property>
11.
12.
<!-- SQL dialect -->
13.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
14.
15.
<!-- Enable Hibernate's automatic session context management -->
16.
<property name="current_session_context_class">thread</property>
17.
18.
<!-- Disable the second-level cache -->
19.
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</pr
operty>
20.
21.
<!-- Echo all executed SQL to stdout -->
22.
<property name="show_sql">true</property>
23.
24.
<!-- Drop and re-create the database schema on startup -->
25.
<property name="hbm2ddl.auto">update</property>
26.
27.
28.
<mapping class="com.sdnext.hibernate.tutorial.dto.Student">
29.
30.
</mapping></session-factory>
31.
</hibernate-configuration>

HibernateTestDemo.java
view plainprint?

1.
package com.sdnext.hibernate.tutorial;
2.
3.
import java.util.List;
4.
5.
import org.hibernate.Query;
6.
import org.hibernate.Session;
7.
import org.hibernate.SessionFactory;
8.
import org.hibernate.cfg.AnnotationConfiguration;
9.
10.
import com.sdnext.hibernate.tutorial.dto.Student;
11.
12.
public class HibernateTestDemo {
13.
/**
14.
* @param args
15.
*/
16.
public static void main(String[] args)
17.
{
18.
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buil
dSessionFactory();
19.
Session session = sessionFactory.openSession();
20.
session.beginTransaction();
21.
22.
String SQL_QUERY = "FROM Student student";
23.
Query query = session.createQuery(SQL_QUERY);
24.
query.setFirstResult(1);//set first result start value
25.
query.setMaxResults(5);//number of result to be display
26.
27.
List<student> students = query.list();
28.
for(Student student : students)
29.
{
30.
System.out.println(student);
31.
}
32.
session.getTransaction().commit();

33.
34.
35.
36.

session.close();
}
}
</student>

Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select student0_.ID as ID0_, student0_.COURSE as COURSE0_, student0_.ROLL_NUMBER
as ROLL3_0_, student0_.STUDENT_NAME as STUDENT4_0_ from STUDENT student0_ limit ?, ?
ROLL Number: 2| Name: Sweety Rajput| Course: PGDCP
ROLL Number: 3| Name: Adesh Rajput| Course: MA
ROLL Number: 4| Name: DEV| Course: MA
ROLL Number: 5| Name: RAJ| Course: BA
ROLL Number: 6| Name: Pradeep| Course: BA

Parameter Binding and SQL Injection :


Chapter 28
Parameter binding means is way to bind parameter with SQL to use in the hibernate for particular criteria.

SQL INJECTION:
Injecting the value to the SQL statement. SQL injection refers to the act of someone inserting a MySQL statement
to be run on your database without your knowledge. Injection usually occurs when you ask a user for input, like
their name, and instead of a name they give you a MySQL statement that you will unknowingly run on your
database.
Normal: " SELECT * FROM student WHERE studentName= 'sweety'"
Injection: "SELECT * FROM student WHERE studentName= '' +studentName

PARAMETER BINDING:
A bind variable is a named placeholder (preceded by a colon) that is embedded in the query string in place of a
literal. The actual value is substituted at runtime using the setParameter() method.
Without parameter binding, you have to concatenate the parameter String like this (bad code) :
view plainprint?

1.
"'";
2.
3.

String hql = "from Student student where student.studentName = '" + studentName+


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

Pass an unchecked value from user input to the database will raise security concern, because it can easy get hack
by SQL injection. You have to avoid the above bad code and using parameter binding instead.

Hibernate parameter binding


There are two ways to parameter binding :
1.

Named parameters binding

2.

Positional parameters binding.

1. Named Parameters Binding:


This is the most common and user friendly way. It use colon followed by a parameter name (:example) to define a
named parameter. See examples

Example 1 setParameter
The setParameter is smart enough to discover the parameter data type for you.
view plainprint?

1.
2.
3.
4.

String hql = "from Student student where student.rollNumber= :rollNumber";


Query query = session.createQuery(hql);
query.setParameter("rollNumber", "3");
List result = query.list();

Example 2 setString
You can use setString to tell Hibernate this parameter date type is String.
view plainprint?

1.
2.
3.
4.

String hql = "from Student student where student.studentName= :studentName";


Query query = session.createQuery(hql);
query.setString("studentName", "Sweety Rajput");
List result = query.list();

Example 3 setProperties
This feature is great ! You can pass an object into the parameter binding. Hibernate will automatic check the
objects properties and match with the colon parameter.
view plainprint?

1.
2.
3.
4.
5.
6.

Student student= new Student();


student.setCourse("MCA");
String hql = "from Student student where student.course= :course";
Query query = session.createQuery(hql);
query .setProperties(student);
List result = query.list();

2. Positional parameters
Its use question mark (?) to define a named parameter, and you have to set your parameter according to the
position sequence. See example
view plainprint?

1.
String hql = "from Student student where student.course= ? and student.studentNa
me = ?";
2.
Query query = session.createQuery(hql);
3.
query.setString(0, "MCA");
4.
query.setParameter(1, "Dinesh Rajput")
5.
List result = query.list();

In Hibernate parameter binding, i would recommend always go for "Named parameters", as its more easy
to maintain, and the compiled SQL statement can be reuse (if only bind parameters change) to increase
the performance.

Named Queries in Hibernate : Chapter 29


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 "named queries" , it lets
developer to put all HQL into the XML mapping fileor via annotation.

Named Query is very useful concept in hibernate. It lets you separate queries from coding section of the
application to themapping xml file(.hbm files). The query is given unique name for the entire
application. The application can use the query by using the name of the query. This way the application is
able to use the same query multiple times without writing the same query multiple times.

1. XML mapping file:


student.hbm.xml
Native SQL in mapping file:
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.Student" table="STUDENT">
<id column="ID" name="id" type="int">
<generator class="increment">
</generator></id>
<property name="rollNumber" type="int">
<column name="ROLL_NUMBER">
</column></property>
<property name="studentName" type="String">
<column name="STUDENT_NAME"></column>

12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.

</property>
<property name="course" type="String">
<column name="COURSE"></column>
</property>
</class>
<sql-query name="findStudentByRollNumber">
<return alias="student" class="com.sdnext.hibernate.tutorial.dto.Student">
<!--[CDATA[
select * from Student student where student.rollNumber = :rollNumber
]]-->
</return>
</sql-query>
</hibernate-mapping>

HQL in mapping file


view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.

<hibernate-mapping>
<class name="com.sdnext.hibernate.tutorial.dto.Student" table="STUDENT">
<id column="ID" name="id" type="int">
<generator class="increment">
</generator></id>
<property name="rollNumber" type="int">
<column name="ROLL_NUMBER">
</column></property>
<property name="studentName" type="String">
<column name="STUDENT_NAME"></column>
</property>
<property name="course" type="String">
<column name="COURSE"></column>
</property>
</class>
<query name="findStudentByRollNumber">
<!--[CDATA[
from Student student where student.rollNumber = :rollNumber
]]-->
</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.
hibernate.cfg.xml
view plainprint?

1.
<hibernate-configuration>
2.
<session-factory>
3.
<!-- Database connection settings -->
4.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
5.
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB2</pro
perty>
6.
<property name="connection.username">root</property>
7.
<property name="connection.password">root</property>
8.
9.
<!-- JDBC connection pool (use the built-in) -->

10.
<property name="connection.pool_size">1</property>
11.
12.
<!-- SQL dialect -->
13.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
14.
15.
<!-- Enable Hibernate's automatic session context management -->
16.
<property name="current_session_context_class">thread</property>
17.
18.
<!-- Disable the second-level cache -->
19.
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</pr
operty>
20.
21.
<!-- Echo all executed SQL to stdout -->
22.
<property name="show_sql">true</property>
23.
24.
<!-- Drop and re-create the database schema on startup -->
25.
<property name="hbm2ddl.auto">update</property>
26.
27.
28.
<mapping resource="student.hbm.xml">
29.
30.
</mapping></session-factory>
31.
</hibernate-configuration>
32.

HibernateTestDemo.java
view plainprint?

1.
package com.sdnext.hibernate.tutorial;
2.
3.
import java.util.List;
4.
5.
import org.hibernate.Query;
6.
import org.hibernate.Session;
7.
import org.hibernate.SessionFactory;
8.
import org.hibernate.cfg.Configuration;
9.
10.
import com.sdnext.hibernate.tutorial.dto.Student;
11.
12.
public class HibernateTestDemo {
13.
/**
14.
* @param args
15.
*/
16.
public static void main(String[] args)
17.
{
18.
SessionFactory sessionFactory = new Configuration().configure().buildSessionFa
ctory();
19.
Session session = sessionFactory.openSession();
20.
session.beginTransaction();
21.
22.
Query query = session.getNamedQuery("findStudentByRollNumber").setInteger("rol
lNumber", 3);
23.
24.
List<student> students = query.list();
25.
for(Student student : students)
26.
{
27.
System.out.println(student);
28.
}
29.
session.getTransaction().commit();
30.
session.close();
31.
}

32.
33.

}
</student>

2. Annotation:
HQL in annotation
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

@NamedQueries({
@NamedQuery(
name = "findStudentByRollNumber",
query = "from Student student where student.rollNumber = :rollNumber"
)
})
@Entity
@Table(name = "STUDENT")
public class Student implements java.io.Serializable {
...

Native SQL in annotation


view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

@NamedNativeQueries({
@NamedNativeQuery(
name = "findStudentByRollNumber",
query = "select * from Student student where student.rollNumber = :rollNumbe"
resultClass = Student.class
)
})
@Entity
@Table(name = "STUDENT")
public class Student 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".
Example:
Student.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.

package com.sdnext.hibernate.tutorial.dto;
import java.io.Serializable;
import
import
import
import
import
import
import
import

javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.NamedQueries;
javax.persistence.NamedQuery;
javax.persistence.Table;

@NamedQueries({
@NamedQuery(
name = "findStudentByRollNumber",
query = "from Student student where student.rollNumber = :rollNumber"
)

19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.

})
@Entity
@Table(name="STUDENT")
public class Student implements Serializable
{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 8633415090390966715L;
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="STUDENT_NAME")
private String studentName;
@Column(name="ROLL_NUMBER")
private int rollNumber;
@Column(name="COURSE")
private String course;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getRollNumber() {
return rollNumber;
}
public void setRollNumber(int rollNumber) {
this.rollNumber = rollNumber;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public String toString()
{
return "ROLL Number: "+rollNumber+"| Name: "+studentName+"| Course: "+course;

65.
66.

}
}

hibernate.cfg.xml
view plainprint?

1.
<hibernate-configuration>
2.
<session-factory>
3.
<!-- Database connection settings -->
4.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
5.
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB2</pro
perty>
6.
<property name="connection.username">root</property>
7.
<property name="connection.password">root</property>

8.
9.
<!-- JDBC connection pool (use the built-in) -->
10.
<property name="connection.pool_size">1</property>
11.
12.
<!-- SQL dialect -->
13.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
14.
15.
<!-- Enable Hibernate's automatic session context management -->
16.
<property name="current_session_context_class">thread</property>
17.
18.
<!-- Disable the second-level cache -->
19.
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</pr
operty>
20.
21.
<!-- Echo all executed SQL to stdout -->
22.
<property name="show_sql">true</property>
23.
24.
<!-- Drop and re-create the database schema on startup -->
25.
<property name="hbm2ddl.auto">update</property>
26.
27.
28.
<mapping class="com.sdnext.hibernate.tutorial.dto.Student">
29.
30.
</mapping></session-factory>
31.
</hibernate-configuration>

HibernateTestDemo.java
view plainprint?

1.
package com.sdnext.hibernate.tutorial;
2.
3.
import java.util.List;
4.
5.
import org.hibernate.Query;
6.
import org.hibernate.Session;
7.
import org.hibernate.SessionFactory;
8.
import org.hibernate.cfg.AnnotationConfiguration;
9.
10.
import com.sdnext.hibernate.tutorial.dto.Student;
11.
12.
public class HibernateTestDemo {
13.
/**
14.
* @param args
15.
*/
16.
public static void main(String[] args)
17.
{
18.
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buil
dSessionFactory();
19.
Session session = sessionFactory.openSession();
20.
session.beginTransaction();
21.
22.
Query query = session.getNamedQuery("findStudentByRollNumber").setInteger("rol
lNumber", 3);
23.
24.
List<student> students = query.list();
25.
for(Student student : students)
26.
{
27.
System.out.println(student);
28.
}
29.
session.getTransaction().commit();
30.
session.close();

31.
32.
33.

}
}
</student>

Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select student0_.ID as ID0_, student0_.COURSE as COURSE0_,
student0_.ROLL_NUMBER as ROLL3_0_, student0_.STUDENT_NAME as STUDENT4_0_ from
STUDENT student0_ where student0_.ROLL_NUMBER=?
ROLL Number: 3| Name: Adesh Rajput| Course: MA

Criteria API in Hibernate : Chapter 30


There are three way to pulling data from the database in the Hibernate.
1.
Using session methods(get() and load() methods) -limited control to accessing data
2.
Using HQL - Slightly more control using where clause and other clauses but there are
some problems here... is more complicated to maintain in case of bigger queries with lots of
clauses.
3.
Using Criteria API
WHAT IS CRITERIA API?
The API (Application Programming Interface) of Hibernate Criteria provides an elegant way of building
dynamic query on the persistence database.
The hibernate criteria API is very Simplified API for fetching data from Criterion objects. The criteria API is
an alternative of HQL (Hibernate Query Language) queries. It is more powerful and flexible for writing
tricky criteria functions and dynamic queries
1. Using Criteria API to create criteria:
view plainprint?

1.

Criteria criteria = session.createCriteria(Student.class);

2. The Criteria API supports all the comparision operators such as =, <, >, >=,=<, etc in the
supported Expression class eq(), lt(), gt(), le() , ge() respectively.
view plainprint?

1.
2.
3.
4.
5.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.eq("studentName", "Dinesh Rajput"));
criteria.add(Restrictions.le("rollNumber", 1));

3. Criteria ordering query


The result is sort by "studentName" in ascending order.
view plainprint?

1.
2.

Criteria criteria = session.createCriteria(Student.class);


criteria.addOrder(Order.asc("studentName"));

The result is sort by "studentName" in descending order.


view plainprint?

1.
2.

Criteria criteria = session.createCriteria(Student.class);


criteria.addOrder(Order.desc("studentName"));

4. Criteria paging the result


Criteria provide some functions to make pagination extremely easy. Starting from the 5th record, and
retrieve the next 10 records from database.
view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.setMaxResults(10);
criteria.setFirstResult(5);

Problem with Criteria API


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.
Student.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.

package com.sdnext.hibernate.tutorial.dto;
import java.io.Serializable;
import
import
import
import
import
import

javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.Table;

@Entity
@Table(name="STUDENT")
public class Student implements Serializable
{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 8633415090390966715L;
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="STUDENT_NAME")
private String studentName;
@Column(name="ROLL_NUMBER")
private int rollNumber;
@Column(name="COURSE")
private String course;
public int getId() {

32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.

return id;
}
public void setId(int id) {
this.id = id;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getRollNumber() {
return rollNumber;
}
public void setRollNumber(int rollNumber) {
this.rollNumber = rollNumber;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public String toString()
{
return "ROLL Number: "+rollNumber+"| Name: "+studentName+"| Course: "+course;
}
}

hibernate.cfg.xml
view plainprint?

1.
<hibernate-configuration>
2.
<session-factory>
3.
<!-- Database connection settings -->
4.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
5.
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB2</pro
perty>
6.
<property name="connection.username">root</property>
7.
<property name="connection.password">root</property>
8.
9.
<!-- JDBC connection pool (use the built-in) -->
10.
<property name="connection.pool_size">1</property>
11.
12.
<!-- SQL dialect -->
13.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
14.
15.
<!-- Enable Hibernate's automatic session context management -->
16.
<property name="current_session_context_class">thread</property>
17.
18.
<!-- Disable the second-level cache -->
19.
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</pr
operty>
20.
21.
<!-- Echo all executed SQL to stdout -->
22.
<property name="show_sql">true</property>
23.
24.
<!-- Drop and re-create the database schema on startup -->
25.
<property name="hbm2ddl.auto">update</property>
26.
27.

28.
29.
30.
31.

<mapping class="com.sdnext.hibernate.tutorial.dto.Student">
</mapping></session-factory>
</hibernate-configuration>

HibernateTestDemo.java
view plainprint?

1.
package com.sdnext.hibernate.tutorial;
2.
3.
import java.util.List;
4.
5.
import org.hibernate.Criteria;
6.
import org.hibernate.Session;
7.
import org.hibernate.SessionFactory;
8.
import org.hibernate.cfg.AnnotationConfiguration;
9.
import org.hibernate.criterion.Restrictions;
10.
11.
import com.sdnext.hibernate.tutorial.dto.Student;
12.
13.
14.
public class HibernateTestDemo {
15.
16.
/**
17.
* @param args
18.
*/
19.
public static void main(String[] args)
20.
{
21.
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buil
dSessionFactory();
22.
Session session = sessionFactory.openSession();
23.
session.beginTransaction();
24.
25.
Criteria criteria = session.createCriteria(Student.class);
26.
criteria.add(Restrictions.eq("studentName", "Dinesh Rajput"));
27.
28.
List<student> students = criteria.list();
29.
30.
for(Student student : students)
31.
{
32.
System.out.println(student);
33.
}
34.
session.getTransaction().commit();
35.
session.close();
36.
}
37.
38.
}
39.
</student>

Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select this_.ID as ID0_0_, this_.COURSE as COURSE0_0_, this_.ROLL_NUMBER as
ROLL3_0_0_, this_.STUDENT_NAME as STUDENT4_0_0_ from STUDENT this_ where
this_.STUDENT_NAME=?
ROLL Number: 1| Name: Dinesh Rajput| Course: MCA

In the Next Chapter we will discuss more about the Criteria Query with
Restriction.

Restrictions in Hibernate : Chapter 31


In this chapter, you will see the use of Restrictions class in java. It is used to restrict the retrieval of data
from database.
Syntax:
view plainprint?

1.
2.

Criteria criteria = session.createCriteria(Model.class);


criteria.add(Restrictions.eq(propertyName, propertyValue));

Criteria restrictions query


The Restrictions class provide many methods to do the comparison operation.
Restrictions.eq
This is used to apply an "equal" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber = 3;

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.eq("rollNumber", 3));
List list = criteria.list();

Restrictions.lt
This is used to apply a "less than" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber < 3;

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.lt("rollNumber", 3));
List list = criteria.list();

Restrictions.gt
This is used to apply a "greater than" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber > 3;

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.gt("rollNumber", 3));
List list = criteria.list();

Restrictions.le
This is used to apply a "less than or equal" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber <= 3;

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.le("rollNumber", 3));
List list = criteria.list();

Restrictions.ge
This is used to apply a "greater than or equal" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber >= 3;

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.ge("rollNumber", 3));
List list = criteria.list();

Restrictions.ne
This is used to apply a "not equal" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber <> 3;

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.ne("rollNumber", 3));
List list = criteria.list();

Restrictions.in
This is used to apply an "in" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber IN (3,5,7);

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.in("rollNumber", new Integer[]{3,5,7}));
List list = criteria.list();

Restrictions.or
This returns the disjunction of two expressions.
Simple SQL query >>

view plainprint?

1.

SELECT * FROM student WHERE rollNumber > 3 OR course='MA';

Above query in Criteria API >>


view plainprint?

1.
Criteria criteria = session.createCriteria(Student.class);
2.
criteria.add(Restrictions.or(Restrictions.gt("rollNumber", 3), Restrictions.eq("
course", "MA"));
3.
List list = criteria.list();

Restrictions.not
This returns the negation of an expression.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber NOT IN (3,5,7);

Above query in Criteria API >>


view plainprint?

1.
2.
)));
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.not(Restrictions.in("rollNumber", new Integer[]{3,5,7}
List list = criteria.list();

Restrictions.like
This is used to apply a "like" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE studentName LIKE %RAJPUT%;

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.like("studentName", "%RAJPUT%"));
List list = criteria.list();

Restrictions.isNull
This is used to apply an "is null" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE studentName IS NULL;

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.isNull("studentName"));
List list = criteria.list();

Restrictions.isNotNull
This is used to apply an "is not null" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE studentName IS NOT NULL;

Above query in Criteria API >>


view plainprint?

1.
2.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.isNotNull("studentName"));

3.

List list = criteria.list();

Restriction.between
This is used to apply a "between" constraint to the named property.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM student WHERE rollNumber BETWEEN (3,7);

Above query in Criteria API >>


view plainprint?

1.
2.
3.

Criteria criteria = session.createCriteria(Student.class);


criteria.add(Restrictions.between("rollNumber", 3, 7));
List list = criteria.list();

Restriction.allEq
This is used to apply an "equals" constraint to each property in the key set of a Map.
Simple SQL query >>
view plainprint?

1.

SELECT * FROM user WHERE userName = +userName AND userPassword = +userPassword;

Above query in Criteria API >>


view plainprint?

1.
2.
3.
4.
5.
6.

Map map = new HashMap();


map.put("username", username);
map.put("userPassword", userPassword);
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.allEq(map));
List list = criteria.uniqueResult();

Cacheing in Hibernate: First Level and Second


Level Cache in Hibernate : Chapter 32
In earlier we said that hibernate much more than an ORM tool i.e. Hibernate provide the lots of
other features. In which Cache is very important feature one of them. Hibernate is actually a
very powerful, consistent, and reliable database mapping tool. Mapping between objects in Java
to relational databases has many facets that you must be aware of. Hibernate does a
particularly good job of making the process simple to start, and providing the facilities to allow it
to scale well and meet exceedingly complex mapping demands.
Caching is all about application performance optimization and it sits between your application and the
database to avoid the number of database hits as many as possible to give a better performance for
performance critical applications.
Caching is important to Hibernate as well which utilizes a multilevel caching schemes as explained below:

One of the primary concerns of mappings between a database and our Java application
is performance. This is the common concern of the all guys who working with hibernate and
spent the more time in ORM tools for performance-enhancing changes to particular queries and
retrievals. Today I want to discuss about some facets of the Hibernate infrastructure that are
implemented to handle certain performance concerns 1.
The first-level cache - Session (Earlier hibernate already provide this level of cache)
2.
The second-level cache -Session-factory-level cache
3.
and the query cache.
The first-level cache: The first level cache type is the session cache. The session cache caches object
within the current session but this is not enough for long level i.e. session factory scope.
The second-level cache: The second-level cache is called 'second-level' because there is already a
cache operating for you in Hibernate for the duration you have a session open. A Hibernate Session is a
transaction-level cache of persistent data. It is possible to configure a SessionFactory-level cache on a
class-by-class and collection-by-collection basis.
second-level cache
-- Across sessions in an Application
-- Across applications (different applications on same servers with same database)
-- Across clusters (different applications on different servers with same database)

NOTE: Be careful Caches are never aware of changes made to the persistent store by another
application i.e. suppose one application deploy one server with using hibernate and get the data from
database and put to the cache for further using purpose but another application deployed another server
which does not using any ORM tool so it does mot know about Cache and direct interacting with
database and may be update data of database. Now data in Cache is invalid.

Hibernate uses first-level cache by default and you have nothing to do to use first-level cache. Let's go
straight to the optional second-level cache. Not all classes benefit from caching, so it's important to be
able to disable the second-level cache.
The 'second-level' cache exists as long as the session factory is alive. The second-level cache holds on
to the 'data' for all properties and associations (and collections if requested) for individual entities that are
marked to be cached.
In hibernate configuration file (hibernate.cfg.xml) we wrote the following line.
For Disabling the second level of cache we have to made following change to hibernate configuration file.
view plainprint?

1.
2.
rty>

<!-- Disable the second-level cache -->


<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</prope

For Enabling the second level of cache we have to made following change to hibernate configuration file.
view plainprint?

1.
<!-- Enable the second-level cache -->
2.
<property name="cache.use_second_level_cache">true</property>
3.
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</pr
operty>

1. Cache Strategy using with Annotation as some changes made to the Model class also.
view plainprint?

1.
2.
3.
4.
5.
6.
7.

@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name="STUDENT")
public class Student implements Serializable
{
....

2. Cache Strategy using with Mapping file(.hbm.xml) .


view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
>
11.
12.
13.

<hibernate-mapping>
<class name="Student" table="STUDENT">
This class contains the student detail.
<cache usage="read-only">
<id column="ID" name="id" type="java.lang.Long">
<generator class="native">
</generator></id>
<property column="STUDENT_NAME" name="studentName" type="java.lang.String"
<property column="lCOURSE" name="course" type="java.lang.String">
<property column="ROLL_NUMBER" name="rollNumber" type="java.lang.Long">
</property></property></property></cache></class>

14.

</hibernate-mapping>

CONCURRENCY STRATEGIES:
A concurrency strategy is a mediator which responsible for storing items of data in the cache and
retrieving them from the cache. If you are going to enable a second-level cache, you will have to decide,
for each persistent class and collection, which cache concurrency strategy to use.
1.
Transactional: Use this strategy for read-mostly data where it is critical to prevent stale
data in concurrent transactions,in the rare case of an update.
2.
Read-write: Again use this strategy for read-mostly data where it is critical to prevent
stale data in concurrent transactions,in the rare case of an update.
3.
Nonstrict-read-write: This strategy makes no guarantee of consistency between the
cache and the database. Use this strategy if data hardly ever changes and a small likelihood of
stale data is not of critical concern.
4.
Read-only: A concurrency strategy suitable for data which never changes. Use it for
reference data only.
You have to download one more jar (ehcache-core-2.5.2) and configure with your application as given in
below..

Now look the following example which describe the Second Level Of Cache i.e. Across the sessions.

HibernateTestDemo.java
view plainprint?

1.
package com.sdnext.hibernate.tutorial;
2.
3.
import org.hibernate.Session;
4.
import org.hibernate.SessionFactory;
5.
import org.hibernate.cfg.AnnotationConfiguration;
6.
7.
import com.sdnext.hibernate.tutorial.dto.Student;
8.
9.
10.
public class HibernateTestDemo {
11.
12.
/**
13.
* @param args
14.
*/
15.
public static void main(String[] args)
16.
{
17.
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buil
dSessionFactory();
18.
Session session = sessionFactory.openSession();
19.
session.beginTransaction();
20.
21.
Student student = (Student) session.get(Student.class, 1);
22.
23.
session.getTransaction().commit();
24.
session.close();
25.
26.
Session session2 = sessionFactory.openSession();
27.
session2.beginTransaction();
28.
29.
Student student2 = (Student) session2.get(Student.class, 1);
30.
31.
session2.getTransaction().commit();
32.
session2.close();
33.
}
34.
}

Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select student0_.ID as ID0_0_, student0_.COURSE as COURSE0_0_,
student0_.ROLL_NUMBER as ROLL3_0_0_, student0_.STUDENT_NAME as STUDENT4_0_0_ from
STUDENT student0_ where student0_.ID=?

As we seen the output there is only one query execute but we called get method for same model object
two times i.e. when retrieve the model object first time it cache to the second level cache when we call
second get of second session object for the same model object it does not execute select query again
because hibernate return this model object from the session.

In the Next Chapter we will discuss more about the Query Cacheing in Hibernate.

Using Query Cache in Hibernate : Chapter 33


In current chapter I am going to explain how to use Hibernate Query Cache to avoid amount of traffic
between your application and database. The query cache is responsible for caching the results of
queries. Let us have a look how Hibernate uses the query cache to retrieve objects.
Note that the query cache does not cache the state of the actual entities in the result set; it caches only
identifier values and results of value type. So the query cache should always be used in conjunction with
the second-level cache.
How the Query Cache Works:
view plainprint?

1.
Query query = session.createQuery("from Student as student where student.id = ?
and student.studentName = ?");
2.
query.setInt(0, Integer.valueOf(1));
3.
query.setString(1, "Dinesh Rajput");
4.
query.setCacheable(true);
5.
List l = query.list();

The query cache works something like this:


*---------------------------------------------------------------------------------------*
|
Query Cache
|
|---------------------------------------------------------------------------------------|
| ["from Student as student where student.id = ? and student.studentName =
?", [ 1 , "Dinesh Rajput"] ] -> [ 2 ] ] |
*---------------------------------------------------------------------------------------*
The combination of the query and the values provided as parameters to that query is used as a key, and
the value is the list of identifiers for that query. Note that this becomes more complex from an internal
perspective as you begin to consider that a query can have an effect of altering associations to objects
returned that query; not to mention the fact that a query may not return whole objects, but may in fact only
return scalar values (when you have supplied a select clause for instance). That being said, this is a
sound and reliable way to think of the query cache conceptually.

Using the query cache


Two hibernate properties control whether the query cache is enabled:

hibernate.cache.use_second_level_cache=true|false

hibernate.cache.use_query_cache=true|false

The first turns on the second level cache in general and the second turns on the query cache regions. If
the second is set to false, the query and timestamp cache regions are not created or used.

Hibernate Batch Processing : Chapter 34


Posted by Dinesh Rajput

Suppose there is one situation in which you have to insert 1000000 records in to database in a time. So
what to do in this situation...
In Native Solution in the Hibernate
view plainprint?

1.
2.
3.

Session session = sessionFactory.openSession();


Transaction tx = session.beginTransaction();
for ( int i=0; i<1000000; i++ )

4.
5.
6.
7.
8.
9.

{
Student student = new Student(.....);
session.save(student);
}
tx.commit();
session.close();

Because by default, Hibernate will cache all the persisted objects in the session-level cache and
ultimately your application would fall over with an OutOfMemoryException somewhere around the
50,000th row. You can resolve this problem if you are using batch processing with Hibernate.
To use the batch processing feature, first set hibernate.jdbc.batch_size as batch size to a number either
at 20 or 50 depending on object size. This will tell the hibernate container that every X rows to be inserted
as batch. To implement this in your code we would need to do little modification as follows:
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.

Session session = SessionFactory.openSession();


Transaction tx = session.beginTransaction();
for ( int i=0; i<1000000; i++ )
{
Student student = new Student(.....);
session.save(employee);
if( i % 50 == 0 ) // Same as the JDBC batch size
{
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();

Above code will work fine for the INSERT operation, but if you want to make UPDATE operation then you
can achieve using the following code:
view plainprint?

1.
2.
3.

Session session = sessionFactory.openSession();


Transaction tx = session.beginTransaction();
ScrollableResults studentCursor = session.createQuery("FROM STUDENT").scroll();

4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.

int count = 0;
while(studentCursor .next())
{
Student student = (Student) studentCursor.get(0);
student.setName("DEV");
seession.update(student);
if ( ++count % 50 == 0 ) {
session.flush();
session.clear();
}
}
tx.commit();
session.close();

In Batch Processing Solution in the Hibernate


If you are undertaking batch processing you will need to enable the use of JDBC batching. This is
absolutely essential if you want to achieve optimal performance. Set the JDBC batch size to a reasonable
number (10-50).
hibernate.jdbc.batch_size 50
You can also do this kind of work in a process where interaction with the second-level cache is
completely disabled:
hibernate.cache.use_second_level_cache false

hibernate.cfg.xml
view plainprint?

1.
<hibernate-configuration>
2.
<session-factory>
3.
4.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
5.
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB2</pro
perty>
6.
<property name="connection.username">root</property>
7.
<property name="connection.password">root</property>
8.
9.
10.
<property name="connection.pool_size">1</property>
11.
12.
13.
<property name="hibernate.jdbc.batch_size"> 50 </property>
14.
15.
16.
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
17.
18.
19.
<property name="current_session_context_class">thread</property>
20.
21.
22.
<property name="hibernate.cache.use_second_level_cache">false</property>
23.
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</pr
operty>
24.
25.
26.
<property name="show_sql">true</property>
27.
28.
29.
<property name="hbm2ddl.auto">update</property>
30.
31.
32.
<mapping class="com.sdnext.hibernate.tutorial.dto.Student">
33.
34.
</mapping></session-factory>
35.
</hibernate-configuration>

Student.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.

package com.sdnext.hibernate.tutorial.dto;
import java.io.Serializable;
import
import
import
import
import
import

javax.persistence.Column;
javax.persistence.Entity;
javax.persistence.GeneratedValue;
javax.persistence.GenerationType;
javax.persistence.Id;
javax.persistence.Table;

@Entity
@Table(name="STUDENT")
public class Student implements Serializable
{
/**

17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.

* serialVersionUID
*/
private static final long serialVersionUID = 8633415090390966715L;
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="STUDENT_NAME")
private String studentName;
@Column(name="ROLL_NUMBER")
private int rollNumber;
@Column(name="COURSE")
private String course;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getRollNumber() {
return rollNumber;
}
public void setRollNumber(int rollNumber) {
this.rollNumber = rollNumber;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public String toString()
{
return "ROLL Number: "+rollNumber+"| Name: "+studentName+"| Course: "+course;
}
}

HibernateTestDemo.java
view plainprint?

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.

package com.sdnext.hibernate.tutorial;
import
import
import
import

org.hibernate.Session;
org.hibernate.SessionFactory;
org.hibernate.Transaction;
org.hibernate.cfg.AnnotationConfiguration;

import com.sdnext.hibernate.tutorial.dto.Student;

public class HibernateTestDemo {


/**
* @param args
*/

16.
public static void main(String[] args)
17.
{
18.
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buil
dSessionFactory();
19.
Session session = sessionFactory.openSession();
20.
Transaction transaction = session.beginTransaction();
21.
22.
for ( int i=0; i<100000; i++ )
23.
{
24.
String studentName = "DINESH " + i;
25.
int rollNumber = 9 + i;
26.
String course = "MCA " + i;
27.
Student student = new Student();
28.
student.setStudentName(studentName);
29.
student.setRollNumber(rollNumber);
30.
student.setCourse(course);
31.
session.save(student);
32.
if( i % 50 == 0 )
33.
{
34.
session.flush();
35.
session.clear();
36.
}
37.
}
38.
transaction.commit();
39.
session.close();
40.
}
41.
42.
}

Output: .................................
..................................
....................................
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
Hibernate: insert into STUDENT (COURSE, ROLL_NUMBER, STUDENT_NAME) values (?, ?, ?)
....................................
.................................
..............................

This will create 100000 records in STUDENT table.


Hibernate batch processing is powerful but it has many pitfalls that developers must be aware of in order
to use it properly and efficiently. Most people who use batch probably find out about it by trying to perform
a large operation and finding out the hard way why batching is needed. They run out of memory. Once
this is resolved they assume that batching is working properly. The problem is that even if you are
flushing your first level cache, you may not be batching your SQL statements.
Hibernate flushes by default for the following reasons:
1. Before some queries
2. When commit() is executed
3. When session.flush() is executed
The thing to note here is that until the session is flushed, every persistent object is placed into the first
level cache (your JVM's memory). So if you are iterating over a million objects you will have at least a
million objects in memory.
To avoid this problem you need to call the flush() and then clear() method on the session at regular
intervals. Hibernate documentation recommends that you flush every n records where n is equal to the
hibernate.jdbc.batch_size parameter. A Hibernate Batch example shows a trivial batch process.

There are two reasons for batching your hibernate database interactions. The first is to maintain a
reasonable first level cache size so that you do not run out memory. The second is that you want to batch
the inserts and updates so that they are executed efficiently by the database. The example above will
accomplish the first goal but not the second.
view plainprint?

1.
2.
3.
4.
5.
6.

Student student = new Student();


Address address = new Address();
student.setName("DINESH RAJPUT");
address.setCity("DELHI");
student.setAddress(address);
session.save(student);

The problem is Hibernate looks at each SQL statement and checks to see if it is the same statement as
the previously executed statement. If they are and if it hasn't reached the batch_size it will batch those
two statements together using JDBC2 batch. However, if your statements look like the example above,
hibernate will see alternating insert statements and will flush an individual insert statement for each
record processed. So 1 million new students would equal a total of 2 million insert statements in this case.
This is extremely bad for performance.