Flush() synchronizes the database with pending changes in the persistence context. Close() ends the session and detaches all objects. Clear() detaches all objects but keeps the session open, allowing further work before needing to
2. Workshop topics
Hibernate-What it is ? Hibernate Unidirectional
Mapping
ORM and Issues
One to many
Hibernate Hello World CRUD one to one
Hello world with Servlet many to one
Hibernate Object life cycle many to many
Hibernate Architecture
Object as Component mapping Hibernate Bidirectional
mapping
Hibernate Inheritance
HQL
Native SQL queries
Named Quarries
4. What is Hibernate 3
Hibernate is an Object relation mapping framework since 2001 form
JBoss, a division of Red Hat
It provides tools to get Java Objects in an out of an database
It helps to get their relationship to other object in the database
Classes in Hibernate are plain old java objects and so like any
normal java classes they can participate in relationships like
association, inheritance, polymorphism, composition, and collections.
Provides query and retrieval services
4
5. Hibernate modules of discussion
Our area
Hibernate Core Hibernate for Java, native APIs and XML mapping
metadata
Hibernate Standard Java Persistence API for Java SE and
EntityManager Java EE
Hibernate Map classes with JDK 5.0 annotations
Annotations
Hibernate Shards Horizontal data partitioning framework
Hibernate Validator Data integrity annotations and validation API
Hibernate Search Hibernate integration with Lucene for indexing and
querying data
Hibernate Tools Development tools for Eclipse and Ant
NHibernate The NHibernate service for the .NET framework
JBoss Seam Framework for JSF, Ajax, and EJB 3.0/Java EE 5.0
5
applications
6. Why Hibernate?
No JDBC code writing
Can be used in both managed(application server) and
unmanaged environments( standalone application)
Common way to persistence development for both .NET
and JEE.
SQL can be combined with an object-oriented approach.
6
7. Hibernate in java application
Can be used with
Unmanaged environment
Stand-alone application
Managed environment
Web application
Enterprise application (can be used in place of entity beans)
The same power of SQL can be used with hibernate also.
7
9. ORM
Object Relational
Mapping object to relational world is not easy, as there are points of
mismatches
There are numbers of impedance mismatches between OO world and DB
worlds, and ORM tool must address and provide solutions for that
Identity
Granularity
Associations
Navigation
Inheritance
Data type mismatch
10. Identity
A row is uniquely identified form all other rows by its
primary key
An object's identity does not always translate well to the
concept of primary key of DB world
In Java, What is the meaning of identity of an object?
Its data or its place in memory?
11. Granularity
Objects and tables are at different levels of granularity
Table structure are often de-normalized in order to
support better performance, so table rows can map to
multiple objects, how to map them?
12. Associations
Associations in Java are either unidirectional or
bidirectional and can be represented by one object having
pointer of other object.
Relation between database tables is based on join. table
relationship is always bidirectional, while for object it may
be unidirectional/bidirectional
14. Navigation and associations traversal
Navigating Java Objects to get property information often
require traversal of the object graph.
This can be quite expensive if the objects are distributed or
need to be created before traversed.
Consider getting the address to ship and order
While navigation in database is handled with the help of
single join.
15. Inheritance
Inheritance and Polymorphism are important concepts in
OO world
Database don't have equivalent concepts
Now question is how to map it to database world?
Inheritance examples
16. Data Types
There is mismatch between database data type and object
oriented data types.
Question is how ORM tools can help us to map is
correctly?
17. Hibernate Handles all these issues
Hibernate provides many options to handle all the
previous issues...
20. Hibernate Hello World
Steps:
1. Write a POJO class representing the table
2. Write a hbm file
3. Write cfg file
4. Write a class to test CRUD code
20
29. Simple Hibernate application
Steps:
1. Write a POJO class representing the table
2. Write a hbm file
3. Write cfg file
4. Write a servlet code to connect through hibernate and insert data into
the table.
29
31. Write a hbm file
Other ways to write property:
<property name="firstName"><column name="FIRSTNAME"/>
</property>
Or simply
<property name="firstName“ column=“FIRSTNAME”/>
Type can be explicitly specifies as:
<property name="name" type="java.lang.String" column=" firstName
" length="50" />
32. Write cfg file
cfg file is a Hibernate configuration file that details about the database that is
going to be used by hibernate.
File name is hibernate.cfg.xml.
File must be in the same place where classes are located.
Create an XML file with the name hibernate.cfg.xml in the src folder.
35. Object lifecycle
Persistent objects (like Person object) are synchronized with
the database.
That is, the objects state and the affected database rows are kept the
same whenever either changes!
Domain object are in one of these states;
Transient
Persistence
Detached
An objects state determine if it is kept synchronized with the
database
The presence of a session and certain method calls move an
object between states.
39. Core Interfaces
Used to perform basic CRUD and querying operations
Session
SessionFactory
Configuration
Transaction interface
Query
Criteria
39
40. Session
Primary interface used by Hibernate applications to create, read and delete
operations for instances of mapped entity classes
This instance wraps the JDBC connection and is also used to create
transactions.
The persistent objects (POJO) are associated with exactly one Session.
Once the Session is closed, they are detached.
Instance is created using SessionFactory
Session openSession() throws HibernateException
Session instance is not thread-safe.
Instead each thread/transaction should obtain its own instance from a
SessionFactory.
40
41. SessionFactory
The application obtains Session instances from a SessionFactory
interface
The SessionFactory is created from an configuration object.
SessionFactory sf=cfg.buildSessionFactory();
The SessionFactory is an expensive object to create
It too is created at application start-up time
It should be created once and kept for latter use.
The SessionFactory object is used by all the threads of an applications
it is thread safe object
one SessionFactory object is created per database (where connecting to multiple
sessions)
The SessionFactory is used to create Session Objects
42. Session
The Session object is created from the SessionFactory object
Session session=sf.openSession();
A Session object is lightweight and inexpensive to create.
Session object provides the main interface to accomplish work with the
database
Does the work of getting a physical connection to the database
(hopefully from a connection pool)
Session objects are not thread safe
Session objects shold not be kept open for a long time
Application create and destroy these as needed. Typically they are
created to complete a single unit of work.
When modifications are made to the database, session objects are
used to create a transaction object
43. Transaction
Transaction objects are obtained from the session objects,
when an modification to the database is needed.
Transaction transaction =session.beginTransaction();
The Transaction object provides abstraction for the underlying
implementation
Hibernate with use whatever transaction implementation is available
(JDBC, JTA etc.)
It is optional; allowing developer to use their own transactional
infrastructure.
Transaction objects should be kept open for a short time.
44. How hibernate actually works with JDBC?
By default Hibernate creates a proxy for each of the
entity class in mapping file. This class contain the code to
invoke JDBC.
Proxies are created dynamically by sub-classing the entity
object at runtime.
The subclass has all the methods of the parent, so when a
method on the entity object is called, the proxy loads up
the data from the database and calls the method.
44
45. Persistent object states
The POJO or persistent objects can be in one of the
three states is defined in relation to a persistence context
(that means it is loaded into the Hibernate Session object)
Transient
Persistent
Detached
45
46. Transient state
The instance is not associated with any persistence context.
It has no persistent identity or primary key value.
Transient instances may be made persistent by calling
save(), persist() or saveOrUpdate() of
Session
Serializable save(Object object) throws
HibernateException
Persist the given transient instance, first assigning a generated identifier or
using the current value of the identifier property if the assigned generator
is used. This operation cascades to associated instances if the association is
mapped with cascade="save-update".
46
47. void saveOrUpdate(Object object) throws
HibernateException
Either save(Object) or update(Object) the given instance,
depending upon resolution of the unsaved-value checks.
This operation cascades to associated instances if the association is
mapped with cascade="save-update”
void persist(Object object) throws
HibernateException
Make a transient instance persistent. This operation cascades to
associated instances if the association is mapped with cascade="persist".
47
48. Why do we have 2 methods – save() and
persist()?
With save() the insert statement is executed immediately regardless of
transaction state. It returns the inserted key so you can do something like this:
long newKey = session.save(myObj); So use save() if you need an identifier
assigned to the persistent instance immediately.
With persist(), the insert statement is executed in a transaction, not necessarily
immediately.This is preferable in most cases.
Use persist() if you don't need the insert to happen out-of-sequence
with the transaction and you don't need the inserted key
returned.
48
49. get() and load()
The instance is currently associated with a persistence context. It has a persistent
identity (primary key value) and can have a corresponding row in the database.
Any instance returned by a get() or load() method is persistent. Persistent
instances may be made transient by calling delete().
Object get(Class clazz, Serializable id) throws
HibernateException
Return the persistent instance of the given entity class with the given identifier, or null if
there is no such persistent instance.
If the instance is already associated with the session, return that instance. This method never
returns an uninitialized instance.
Object load(Class clazz, Serializable id) throws
HibernateException
Return the persistent instance of the given entity class with the given identifier,
assuming that the instance exists. This method might return a proxied instance
that is initialized on-demand, when a non-identifier method is accessed.
49
50. get() and load()
Difference between the load() and get() methods is that while
load() assumes that instance exists and may return a proxy and
we cannot guarantee that instance actually exists in the
database (it may have got deleted).
Hence get() must be used instead of load() to determine if an instance exists.
Also note that the load() will throw an exception if instance does not exist.
50
51. Detached
The instance was once associated with a persistence
context/session but not is not attached to it may because the
session was closed.
It has a persistent identity and can have a corresponding row in
the database.
While for persistent instance Hibernate guarantees the
relationship between persistent (database ) identity and Java
identity for detached instance there is no such guarantees .
Detached instances may be made persistent by calling
update(), saveOrUpdate()
The state of a transient or detached instance may also be made
persistent as a new persistent instance by calling merge().
51
52. update()and merge()
void update(Object object) throws
HibernateException
Update the persistent instance with the identifier of the given detached instance.
If there is a persistent instance with the same identifier, an exception is thrown.
This operation cascades to associated instances if the association is mapped
with cascade="save-update".
Object merge(Object object) throws
HibernateException
Copy the state of the given object onto the persistent object with the same
identifier.
This operation cascades to associated instances if the association is mapped
with cascade="merge".
52
54. When
session2.update(c); is
used instead of
session2.merge(c);
This is if there is a persistent
instance with the same
identifier in the session,
update() will throw an
exception!
When
session2.merge(c);
is used the data gets updated
because the instance that the
session is holding gets its
values from the detached
instance when merge is called
on detached instance.
54
55. delete() and refresh()
void delete(Object object) throws
HibernateException
Remove a persistent instance from the datastore. The argument may be an
instance associated with the receiving Session or a transient instance with
an identifier associated with existing persistent state. This operation
cascades to associated instances if the association is mapped with
cascade="delete".
void refresh(Object object) throws
HibernateException
This method is useful to sync the state of the given instance with underlying
database in cases where there are chances that database might have been
altered outside the application as a result of a trigger. This is also useful in
cases where direct SQL is used by the application to update the data.
55
56. flush(), close(), clear
void flush() throws HibernateException
This is the method that actually synchronizing the underlying database with
persistent object held in session memory.
This should be called at the end of a unit of work, before committing the
transaction and closing the session (depending on flush-mode,
Transaction.commit() calls this method).
Connection close() throws HibernateException
End the session by releasing the JDBC connection and cleaning up. It is not strictly
necessary to close the session but at least it must be disconnected by calling
disconnect()
void clear()
Completely clear the session. Evict all loaded instances and cancel all pending
saves, updates and deletions. Do not close open iterators or instances of
ScrollableResults.
56
57. Transaction
Transaction can be set using the methods of Session.
Transaction beginTransaction() throws HibernateException
If Transaction object is associated with the session return that else create a new
transaction.
Transaction getTransaction()
Get the Transaction instance associated with this session
In both the cases the class of the returned Transaction object is determined
by the property hibernate.transaction_factory.
The most common approach is the session-per-request pattern
where a single Hibernate Session has same scope as a single
database transaction.
The Hibernate session can be used for multiple DB operations (save,
query, update) within the same request.
57
58. Transaction methods
void begin() throws HibernateException
void commit() throws HibernateException
void rollback() throws HibernateException
To check if transactions was committed or rolled-back properly
boolean wasRolledBack() throws HibernateException
boolean wasCommitted() throws HibernateException
Code snippet wrapping statements in a transactions:
Session sess = factory.openSession();
Transaction tx;
try { tx = sess.beginTransaction();
//do some work ...
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback(); throw e; }
finally { sess.close(); } 58
59. Mapping file
We have seen in the last session that the mapping file tells
Hibernate what table in the database it has to access, and
what columns in that table it should use.
All persistent entity classes go in between the
<hibernate-mapping> tags, include a class element.
We have also looked at how to map the bean columns to
the database tables. By default, no properties of the class
are considered persistent unless it is specified in hbm.
Some more important things to know about the mapping
files are
Key generation
Relationship management
Lazy loading
59
60. Hibernate persistent class
Class should have a constructor with no arguments.
Implementing Serializable is not compulsory.
However if the object in to be stored in HttpSession
then it will be necessary to make the persistent class
Serializable.
The instance variables of the class represent attributes of
business entity. The accessor and mutator methods needs
to be provided for them as laid out by JavaBean
specification guidelines. However the methods may not be
declared public.
Can contain some business methods also.
60
61. Accessor code
Hibernate uses accessor methods to populate the state
of an object when loading the object from the database.
But what if we have a validation code in the setter
method and we don’t want hibernate to run this
validation while loading the data?
In that case, we need to tell Hibernate to directly access
the instance variables
<property name=“fname“ type=“java.lang.String"
column=“fname” access="field”>
forcing Hibernate to bypass the setter method and access
the instance variable directly.
61
62. Key generation
<id name="id" type="long" column="ID" >
<generator class="native"/>
</id>
There is an alternative <composite-id> declaration that
allows access to legacy data with composite keys. Its use is
strongly discouraged for anything else.
The optional <generator> child element names a Java
class used to generate unique identifiers for instances of
the persistent class.
Hibernate provides a range of built-in key
implementations.
62
63. List of Key generator
Generator Description
It generates identifiers of type long, short or int
that are unique only when no other process is
increment
inserting data into the same table. It should not
the used in the clustered environment.
It supports identity columns in DB2, MySQL, MS
identity SQL Server, Sybase and HypersonicSQL. The
returned identifier is of type long, short or int.
The sequence generator uses a sequence in
DB2, PostgreSQL, Oracle, SAP DB, McKoi or a
sequence
generator in Interbase. The returned identifier is
of type long, short or int
lets the application to assign an identifier to the
assigned object before save() is called. This is the default
strategy if no <generator> element is specified.
63
64. Generator Description
The hilo generator uses a hi/lo algorithm to efficiently
generate identifiers of type long, short or int, given a table
and column (by default hibernate_unique_key and next_hi
hilo respectively) as a source of hi values. The hi/lo algorithm
generates identifiers that are unique only for a particular
database. Do not use this generator with connections
enlisted with JTA or with a user-supplied connection.
The seqhilo generator uses a hi/lo algorithm to efficiently
seqhilo generate identifiers of type long, short or int, given a named
database sequence.
The uuid generator uses a 128-bit UUID algorithm to
generate identifiers of type string, unique within a network
uuid
(the IP address is used). The UUID is encoded as a string of
hexadecimal digits of length 32.
It uses a database-generated GUID string on MS SQL
guid
Server and MySQL.
It picks identity, sequence or hilo depending upon the
native
capabilities of the underlying database. 64
65. Generator Description
retrieves a primary key assigned by a database trigger by
select selecting the row by some unique key and retrieving the
primary key value
uses the identifier of another associated object. Usually used
foreign
in conjunction with a <one-to-one> primary key association.
65
67. Object as Component
Associated Objects: <Components>
Set of Associated objects: <Composite-element>
Components can not exist their own, they share id of the
parent entity
Lets say Person have many attributes and we want to
divide it into two POJO such as Person and Address
Steps:
1. Put reference of Address in Person class
2. Map it into mapping file..as shown on next slide.
69. Set as Composition
Just remove <component.../> with
<set name="addresses">
<key column="aid"></key>
<composite-element class="Address">
<property name="city"></property>
<property name="state"></property>
</composite-element>
</set>
Why?
<key column="aid“/>
As one person has N address, we need to have seperate table with name addresses and fk =aid
that is same as id of person
71. Inheritance
Super class & sub class relationship
Types of inheritance relations in hibernate
1. Table per concrete class <union-subclass>
2. Table per class hierarchy <subclass>
3. Table per class <joined-subclass>
72. Inheritance
Table per concrete class <union-subclass>
here Account class is an abstract class. So no need to map it to database, the
values mapped by sub classes ie SavingAccount and CurrentAccount
Two separate table is going to be created for SavingAccount and
CurrentAccount
Table per class hierarchy <subclass>
Here only one table is going to be created, all fields mapped to single table.
Not very memory efficient, May be faster
Table per class <joined-subclass>
Separate table mapped to all classes in
the hierarchy
74. Table per class hierarchy <subclass>
Single table is created per hierarchy ie some columns of
table may contain nulls.
75. Table per class <joined-subclass>
Table for each class is going to be created.
76. Composite primary key
ore then one field combined as primray key. let consider
public class Person {
private int id;
private String name;
private String city;
private String country;
lets say we want to consider id +name as composite pk
better to create an seperate table for ID
Create an seperate class ie PersonID
87. One to many
bi-directional
In bi-directional mapping we can navigate from both the
directions.
i.e. One can navigate from Person to Address and vice
versa.
90. HQL
Hibernate Query Language (HQL) is used similarly to SQL
The main difference between is HQL uses class name instead of table
name, and property names instead of column name.
HQL is extremely simple to learn and use, and the code is always self-
explanatory
We have already used HQL if you remember:
93. HQL Insert Query Example
In HQL, only the INSERT INTO … SELECT … is
supported; there is no INSERT INTO … VALUES.
HQL only support insert from another table. For example
95. Native SQL queries
In Hibernate, HQL or criteria queries should be able to
let you to execute almost any SQL query you want.
However, many developers are complaint about the
Hibernates generated SQL statement is slow and more
prefer to generated their own SQL (native SQL)
statement
96. Native SQL queries example
Hibernate provide a createSQLQuery method to let
you call your native SQL statement directly.
In this example, you tell Hibernate to return you a Stock.class,
all the select data (*) will match to your Stock.class properties
automatically.
In this example, Hibernate will return you an Object array
98. Named queries
Sometimes embedding HQL into Java code may make it harder to
maintain.
Named query helps to externalize any HQL queries that can be
statically defined.
The queries are specified in mapping document with the a name.
They are retrieved using method defined in the Session
Query getNamedQuery(String queryName) throws
HibernateException
Parameterized queries can also be written in the mapping document
and this can be retrieved using the same approach that we discussed
in the previous slide.
98
99. Example: Named queries
customer.hbm.xml
<hibernate-mapping>
…
<query name="getCustID">select c.id from Customer as
c where c.email=?</query>
</hibernate-mapping>
In the main
//get Session etc
Query q = session.getNamedQuery("getCustID");
q.setString(0,"mm@yahoo.com");
List id = q.list();
out.println("ID is : " + id.get(0));
…….
……..
99
100. Named Parameters
One of the shortcomings of parameterized query setting
properties using index is that if the index value changes then the
query will not be correct.
The Query’s method
Query setXXX(String nm,XXX x)
allows using named parameters instead of index values.
In customer.hbm.xml
<query name="getCustID">select c.id from
Customer as c where c.email=:email</query>
In the main
Query q = session.getNamedQuery("getCustID");
q.setString("email","mm@yahoo.com");
List id = q.list();
out.println("ID is : " + id.get(0)); 100