You are on page 1of 25

Hibernate

ORM (Object Relational Mapping) is the fundamental concept of Hibernate


framework which maps database tables with Java Objects and then provides various
APIs to perform different types of operations on the data tables.
Hibernate framework simplifies the development of java application to interact with
the database. Hibernate is an open source, lightweight, ORM (Object Relational
Mapping) tool.
An ORM tool simplifies the data creation, data manipulation and data access. It is a
programming technique that maps the object to the data stored in the database.
The ORM tool internally uses the JDBC API to interact with the database.
Benefits Of Hibernate:
a)Doesn't require to map POJO's to table. POJO's can be constructed using columns
in tables.
b)Doesn't require any server can run as Standalone.
c)No need to write code to handle connection or manage resultset.
d)Supports different database dialects. so makes more reusable

Why Should You Use Hibernate ?


Reasons:
Performance :
1.Hibernate employs very agressive, and very intelligent first and second level
caching strategy. This is a major factor in acheiving the high scalability.
2..Hibernate spares you a unnecessary database calls and in persistence state it is
automated persistence then it still increases the performance.
Portability :Hibernates portability accross the relational databases is amazing.It is
literally one configuration paramter change. You only have to change the database
dialect.
Productivity Hibernate reduces the burden of developer by providing much of
the functionality and let the developer to concentrate on business logic.
Maintainability As hibernate provides most of the functionality, the LOC for the
application will be reduced and it is easy to maintain. By automated
object/relational persistence it even reduces the LOC.
Cost Effective : Hibernate is free and open source Cost Effective
Learning curve is short :Since we all have working experience in using Hibernate,
and Hibernate is totally object orientated concept, it will shorted our learning curve.
Learning curve is short :Since we all have working experience in using Hibernate,
and Hibernate is totally object orientated concept, it will shorted our learning curve.

Core classes/interfaces of Hibernate


Configuration (class):

will be Created only once during the application initialization. It represent


the Configuration file required by Hibernate.
Application configuration settings like Database connection details,
Entity/Persistent classes etc. are configured by this interface.
Hibernate connection will be Handled using hibernate.properties and
hibernate.cfg.xml
For the whole application, there will be only one Configuration for a particular
Database.
Syntax:

Configuration config = new Configuration().configure();


SessionFactory (interface ):
SessionFactoryImpl implements

SessionFactory

A SessionFactory is a global object, that represents a particular hibernate


configuration for particular set of mapping metadata.
The delivery of session objects is done by this interface.
It creates or opens a session to talk to a database.
The internal state of session factory is immutable.
For the whole application, there will be generally one SessionFactory for a
particular Configuration and can be shared by all the application threads.
Syntax:

SessionFactory factory = config.buildSessionFactory();

Session (interface):
SessionImpl implements Session.

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


The Session object is lightweight and designed to be instantiated each time
an interaction is needed with the database.
Persistent objects are saved and retrieved through a Session object.
( Persistent objects are instances of POJO classes that you create that
represent rows in the table in the database.
Session objects are not usually thread safe, they should not be kept open for
a long time and they should be created and destroyed them as needed.
You should always use "one session per request" or "one session per
transaction".
The main function of the Session is to offer CRUD operations for instances of
mapped entity classes.
The main function of the Session is to offer create, read and delete
operations for instances of mapped entity classes.
. Instances may exist in one of the following three states at a given point in time:

transient: A new instance of a persistent class which is not associated with a


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

persistent: You can make a transient instance persistent by associating it


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

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

Syntax: Session session = factory.openSession();

Transaction :

Transaction interface that defines the unit of work. It maintains abstraction from
the transaction implementation of JTA/Jdbc.

A transaction is associated with Session.

It contains commit() and rollback() methods to main consistency.

Syntax:
Transaction tx = session.beginTransaction();
Query and Criteria :

Both are interfaces used to perform some user defined queries.


Query syntax looks closer to SQL language.

Criteria syntax is pure object oriented.

Syntax:
Query query = session.createQuery("from Employee e where e.empid = 100");
Criteria criteria =
session.createCriteria(Employee.class).add(Restrictions.eq("empid", 100));

general flow of Hibernate communication with RDBMS ?


General steps:
1 . Load the Hibernate configuration file and create configuration object. It will
automatically load all hbm mapping files.
Configuration cfg = new Configuration().configure(CONFIG_FILE_LOCATION);
2 . Create session factory from configuration object
SessionFactory sessionFactory = cfg.buildSessionFactory();
3.Get
one
session
from
this
session
factory.
Session ses=factory.opensession()
4 . Create HQL query.
Query query = session.createQuery("from EmployeeBean);
5 . Execute query to get list containing Java objects.
ListfinalList = query.list();
Hibernate Methods:
Save:
hibernate save() can be used to save entity to database. We can invoke this method
outside a transaction. If we use this without transaction and we have cascading
between entities, then only the primary entity gets saved unless we flush the
session.
We should avoid save outside transaction boundary, otherwise mapped entities will
not be saved causing data inconsistency. Its very normal to forget flushing the
session because it doesnt throw any exception or warnings.
Hibernate save method returns the generated id immediately, this is possible
because primary object is saved as soon as save method is invoked.
If there are other objects mapped from the primary object, they gets saved at the
time of committing transaction or when we flush the session.
For objects that are in persistent state, save updates the data through update
query. Notice that it happens when transaction is committed. If there are no
changes in the object, there wont be any query fired. If you will run above program
multiple times, you will notice that update queries are not fired next time because
there is no change in the column values.

Hibernate save load entity object to persistent context, if you will update the object
properties after the save call but before the transaction is committed, it will be
saved into database.
Save method stores an object into the database. That means it insert an entry if
the identifier doesnt exist, else it will throw error. If the primary key already
present in the table, it cannot be inserted.
Employee emp = new Employee();
session.save(emp);
Persist:
Hibernate persist is similar to save (with transaction) and it adds the entity object
to the persistent context, so any further changes are tracked. If the object
properties are changed before the transaction is committed or session is flushed, it
will also be saved into database.
Second difference is that we can use persist() method only within the boundary of a
transaction, so its safe and takes care of any cascaded objects.
Finally, persist doesnt return anything so we need to use the persisted object to get
the generated identifier value.
Update:
Update()- This method is used for updating the object using identifier. If the
identifier is missing or doesnt exist, it will throw exception.
saveOrUpdate():
This method calls save() or update() based on the operation. If the identifier exists,
it will call update method else the save method will be called. saveOrUpdate()
method does the following:
If the object is already persistent in the current session, it do nothing
If another object associated with the session has the same identifier, throw an
exception to the caller
If the object has no identifier property, save() the object
If the objects identifier has the value assigned to a newly instantiated object,
save() the object
Refresh():
Sometimes we face situation where we application database is modified with some
external application/agent and thus corresponding hibernate entity in your
application actually becomes out of sync with its database representation i.e.
having old data. In this case, you can use session.refresh() method to re-populate
the entity with latest data available in database.

public void refresh(Object object) throws HibernateException


public void refresh(Object object, LockMode lockMode) throws HibernateException
Merge():
It updates the database with values from a detached entity. Merging is performed
when you desire to have a detached entity changed to persistent state again, with
the detached entitys changes migrated to (or overriding) the database.
If we call merge() method, then it verifies whether the same object is existed in the
cache or not. If the object is existed in the cache then changes are copied in to the
cache. otherwise it will load the values to cache.
The method signatures for the merge operations are:
Object merge(Object object)
Object merge(String entityName, Object object)
Hibernate official documentation give a very good explanation of merge() method:
Copy the state of the given object onto the persistent object with the same
identifier. If there is no persistent instance currently associated with the session, it
will be loaded. Return the persistent instance. If the given instance is unsaved, save
a copy of and return it as a newly persistent instance. The given instance does not
become associated with the session. This operation cascades to associated
instances if the association is mapped with cascade=merge.
So if I take below code for example then below listed points should be clear to you.
EmployeeEntity mergedEmpEntity = session.merge(empEntity);
empEntity is detached entity when it is passed to merge() method.
merge() method will search for an already loaded EmployeeEntity instance with
identifier information taken from empEntity. If such persistent entity is found then it
will be used for updates. Other wise a new EmployeeEntity is loaded into session
using same identifier information as present in empEntity.
Data is copied from empEntity to new found/loaded entity.
Because new/found entity is persistent, all data copied to it from empEntity is
automatically saved into database.
Reference of that new entity is returned from merge() method and is assigned to
mergedEmpEntity variable.
empEntity is still detached entity.
Hibernate getCurrentSession() :
Hibernate SessionFactory getCurrentSession() method returns the session bound to
the context. But for this to work, we need to configure it in hibernate configuration
file like below.
<property name="hibernate.current_session_context_class">thread</property>

Since this session object belongs to the hibernate context, we dont need to close it.
Once the session factory is closed, this session object gets closed. Hibernate
Session objects are not thread safe, so we should not use it in multi-threaded
environment. We can use it in single threaded environment because its relatively
faster than opening a new session.
Hibernate openSession():
Hibernate SessionFactory openSession() method always opens a new session. We
should close this session object once we are done with all the database operations.
We should open a new session for each request in multi-threaded environment. For
web application frameworks, we can choose to open a new session for each request
or for each session based on the requirement.
Hibernate openStatelessSession():
Hibernate SessionFactory openStatelessSession() method returns instance of
StatelessSession. There is another overloaded method where we can pass
java.sql.Connection object to get a stateless session object from hibernate.
StatelessSession does not implement first-level cache and it doesnt interact with
any second-level cache. Since its stateless, it doesnt implement transactional
write-behind or automatic dirty checking or do cascading operations to associated
entities.
Collections are also ignored by a stateless session. Operations performed via a
stateless session bypass Hibernates event model and interceptors. Its more like a
normal JDBC connection and doesnt provide any benefits that come from using
hibernate framework.
However, stateless session can be a good fit in certain situations, for example
where we are loading bulk data into database and we dont want hibernate session
to hold huge data in first-level cache memory.
Difference between load() and get():
load() :
1. Use this method if it is sure that the objects exist.
2. The load() method throws an exception,when the unique id could not found in
the database.
3. The load() method returns proxy by default and the data base will not be
effected until the invocation of the proxy.
get() :

1. Use this method if it is not sure that the objects exist.


2. Returns null when the unique id is unavailable in the database.
3. The data base will be effected immediately.

What is Hibernate Proxy and how it helps in lazy loading?


Hibernate uses proxy object to support lazy loading. Basically when you load data
from tables, hibernate doesnt load all the mapped objects. As soon as you
reference a child or lookup object via getter methods, if the linked entity is not in
the session cache, then the proxy code will go to the database and load the linked
object. It uses javassist to effectively and dynamically generate sub-classed
implementations of your entity objects.
First level Cache :
First level cache is associated with session object and other session objects in
application cannot see it.
The scope of cache objects is of session. Once session is closed, cached objects are
gone forever.
First level cache is enabled by default and you cannot disable it.
When we query an entity first time, it is retrieved from database and stored in first
level cache associated with hibernate session.
If we query same object again with same session object, it will be loaded from
cache and no sql query will be executed.
The loaded entity can be removed from session using evict() method. The next
loading of this entity will again make a database call if it has been removed using
evict() method.
The whole session cache can be removed using clear() method. It will remove all
the entities stored in cache.
Second level cache:
This is apart from first level cache which is available to be used globally in session
factory scope.
Whenever hibernate session try to load an entity, the very first place it look for
cached copy of entity in first level cache (associated with particular hibernate
session).
If cached copy of entity is present in first level cache, it is returned as result of load
method.

If there is no cached entity in first level cache, then second level cache is looked up
for cached entity.
If second level cache has cached entity, it is returned as result of load method. But,
before returning the entity, it is stored in first level cache also so that next
invocation to load method for entity will return the entity from first level cache
itself, and there will not be need to go to second level cache again.
If entity is not found in first level cache and second level cache also, then database
query is executed and entity is stored in both cache levels, before returning as
response of load() method.
Second level cache validate itself for modified entities, if modification has been
done through hibernate session APIs.
If some user or process make changes directly in database, the there is no way that
second level cache update itself until timeToLiveSeconds duration has passed for
that cache region. In this case, it is good idea to invalidate whole cache and let
hibernate build its
cache once again. You can use below code snippet to invalidate whole hibernate
second level cache.
Different vendors have provided the implementation of Second Level Cache.
EH Cache
OS Cache
Swarm Cache
JBoss Cache
Each implementation provides different cache usage functionality. There are four
ways to use second level cache.
read-only: caching will work for read only operation.
nonstrict-read-write: caching will work for read and write but one at a time.
read-write: caching will work for read and write, can be used simultaneously.
transactional: caching will work for transaction.
Configuration :
3 extra steps for second level cache example using EH cache
1) Add 2 configuration setting in hibernate.cfg.xml file
<property
name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
2) Add cache usage setting in hbm file
<cache usage="read-only" />
3) Create ehcache.xml file
<?xml version="1.0"?>
<ehcache>

<defaultCache
maxElementsInMemory="100"
eternal="true"/>
</ehcache>
Hibernate Mappings:
OneToOne:
One Student has one Address.
Parent entity is responsible to define and manage the relations.
Student{
@OneToOne(TargetEntity=Address.class, Cascade = Cascade.ALL)
@JoinColumn(name="Addres_ID")
private Address address;
OneToMany :
one department has many Employees. Relation should be defined and maintained
by both the entities.
Department{
@OneToMany(mappedBy = "department')
private Set<Employee> employees;
}
Employee{
@ManyToOne
@joinColumn(name="DEPT_ID")
private Department department;
}

ManyToMany:
many students can have many courses.
Parent entity is responsible to define and manage relations.

Student{
@ManyToMany
@joinTable( "STUDENT-COURSE", joinColumns =
{ @joinCoulmn(name="STUDENT_ID")} inversejoincolumns=
{ @joincolumn( name="COURSE_ID")})
private Set<Course> course;
}
Course{
@manyToMany ( Mappedby= "course")
}
Hibernate Cascade types:
When we have relationship between entities, then we need to define how the
different operations will affect the other entity. This is done by cascading and there
are different types of it.

JPA Cascade Types


1.

CascadeType.PERSIST : means that save() or persist() operations cascade


to related entities.

2.

CascadeType.MERGE : means that related entities are merged into


managed state when the owning entity is merged.

3.

CascadeType.REFRESH : does the same thing for the refresh() operation.

4.

CascadeType.REMOVE : removes all related entities association with this


setting when the owning entity is deleted.

5.

CascadeType.DETACH : detaches all related entities if a manual detach


occurs.

6.

CascadeType.ALL : is shorthand for all of the above cascade operations.

some important annotations used for Hibernate mapping


Hibernate supports JPA annotations and it has some other annotations
in org.hibernate.annotationspackage. Some of the important JPA and hibernate
annotations used are:
A.

javax.persistence.Entity: Used with model classes to specify that they are


entity beans.

B.

javax.persistence.Table: Used with entity beans to define the


corresponding table name in database.

C.

javax.persistence.Access: Used to define the access type, either field or


property. Default value is field and if you want hibernate to use getter/setter
methods then you need to set it to property.

D.

javax.persistence.Id: Used to define the primary key in the entity bean.

E.

javax.persistence.EmbeddedId: Used to define composite primary key in


the entity bean.

F.

javax.persistence.Column: Used to define the column name in database


table.

G.

javax.persistence.GeneratedValue: Used to define the strategy to be


used for generation of primary key. Used in conjunction
with javax.persistence.GenerationType enum.

H.

javax.persistence.OneToOne: Used to define the one-to-one mapping


between two entity beans. We have other similar annotations
as OneToMany, ManyToOne and ManyToMany

I.

org.hibernate.annotations.Cascade: Used to define the cascading


between two entity beans, used with mappings. It works in conjunction
with org.hibernate.annotations.CascadeType

J.

javax.persistence.PrimaryKeyJoinColumn: Used to define the property


for foreign key. Used with
org.hibernate.annotations.GenericGenerator and org.hibernate.annotations.Para
meter

automatic dirty checking in hibernate


The automatic dirty checking feature of hibernate, calls update statement
automatically on the objects that are modified in a transaction.
Let's understand it by the example given below:...
SessionFactory factory = cfg.buildSessionFactory();
Session session1 = factory.openSession();
Transaction tx=session2.beginTransaction();
Employee e1 = (Employee) session1.get(Employee.class, Integer.valueOf(101));
e1.setSalary(70000);
tx.commit();
session1.close();
Here, after getting employee instance e1 and we are changing the state of e1.
After changing the state, we are committing the transaction. In such case, state will
be updated automatically. This is known as dirty checking in hibernate.
query.scroll() :- Fetching 5000 records from DB using Hibernate.
Hibernate Query Language (HQL) is same as SQL (Structured Query Language)
but it doesn't depends on the table of the database. Instead of table name, we use
class name in HQL. So it is database independent query language.
Advantage of HQL
There are many advantages of HQL. They are as follows:

database independent

supports polymorphic queries

easy to learn for Java Programmer

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

The query interface provides many methods. There is given commonly used
methods:
1. public int executeUpdate() is used to execute the update or delete query.
2. public List list() returns the result of the ralation as a list.
3. public Query setFirstResult(int rowno) specifies the row number from
where record will be retrieved.
4. public Query setMaxResult(int rowno) specifies the no. of records to be
retrieved from the relation (table).
5. public Query setParameter(int position, Object value) it sets the value
to the JDBC style query parameter.
6. public Query setParameter(String name, Object value) it sets the value
to a named query parameter.

Example of HQL to get all the records


1.

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


is Emp
2.
List list=query.list();

Example of HQL to get records with pagination


1.
2.
3.
4.

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


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

Example of HQL update query


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

Transaction tx=session.beginTransaction();
Query q=session.createQuery("update User set name=:n where id=:i");
q.setParameter("n","Udit Kumar");
q.setParameter("i",111);
int status=q.executeUpdate();
System.out.println(status);
tx.commit();

Example of HQL delete query


1.
2.
3.

Query query=session.createQuery("delete from Emp where id=100");


//specifying class name (Emp) not tablename
query.executeUpdate();
HQL with Aggregate functions
You may call avg(), min(), max() etc. aggregate functions by HQL. Let's see some
common examples:
Example to get total salary of all the employees

1.
2.
3.
4.
5.

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


List<Emp> list=q.list();
Iterator<Emp> itr=list.iterator();
while(itr.hasNext()){
System.out.println(itr.next()); }
How to avoid two different threads read the same rows from DB
You need to use PESSIMISTIC_WRITE at query time:

Query q = session
.createQuery("from MyObject n where n.state = 'NEW'")
.setLockOptions(new LockOptions(LockMode.PESSIMISTIC_WRITE));
List<MyObject> list = (List<MyObject>) q.list();

What is need of batch processing in hibernate?


Ans: Consider a scenario in which we need to insert 100000 students in database.
If we insert one by one then we will face out of memory error because hibernate
will keep all the student objects in cache. So to avoid the error, we need to do

batch processing.

Qns-3: How to avoid first level cache in for batch insert?


Ans: Insert objects chunk wise. After every chunk flush the session and also clear
the session to remove first level cache.
for ( int i=0; i<100000; i++ ) {
Student student = new Student();
session.save(student);
if ( i % 15 == 0 ) {
session.flush();
session.clear();
}
}
tx.commit();
session.close();

Qns-4: What is the role of @BatchSize in hibernate?


Ans: If an entity is annotated with @BatchSize, data is not fetched in one go from
the database. Data is fetched according to batch size.

Qns-5: Is HQL query case sensitive?


Ans: Yes. HQL queries are case sensitive.

Qns-6: How to use criteria query?


Ans: Find the sample example.
Criteria c = session.createCriteria(Student.class);
c.setMaxResults(30);
List cats = c.list();

Qns-7: How to narrow results using criteria query?


Ans: Restrictions are used to narrow the results of a criteria query. Find the
sample example.
Criteria c = session.createCriteria(Student.class).add( Restrictions.like("name", "A
%") );
c.setMaxResults(30);
List cats = c.list();

What are detached queries in hibernate?


Ans: While querying detached object, we need DetachedCriteria. DetachedCriteria
allows to create a query outside the scope of session.
DetachedCriteria query = DetachedCriteria.forClass(Student.class)
.add( Property.forName("age").eq('20') );
Transaction t = session.beginTransaction();
List results = query.getExecutableCriteria(session).setMaxResults(100).list();
t.commit();
session.close();

Hibernate Call Store Procedure


1. use createSQLQuery() to call a store procedure directly.

Query query = session.createSQLQuery(


"CALL GetStocks(:stockCode)")
.addEntity(Stock.class)

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

2. Declare your store procedure inside the @NamedNativeQueries annotation.

@NamedNativeQueries({
@NamedNativeQuery(
name = "callStockStoreProcedure",
query = "CALL GetStocks(:stockCode)",
resultClass = Stock.class
)
})
@Entity
@Table(name = "stock")

Hibernate Flush Modes :


static FlushMod ALWAYS
e
The Session is flushed before every query.

static FlushMod AUTO


e

The Session is sometimes flushed before query

execution in order to ensure that queries never return stale


state.
static FlushMod COMMIT
e
The Session is flushed
when Transaction.commit() is called.
static FlushMod MANUAL
e
The Session is only ever flushed
when Session.flush() is explicitly called by the application.

When to use HQL or Criteria Queries

There are lots of different reasons and a ton of opinions on which is better HQL or Criteria Queries. Assuming t
HQL performance is similar in both. Here is a list of why you may prefer one over the other.

Criteria queries are ideal for dynamic queries. It is very simple to add restrictions and ordering as well a

HQL is ideal for static queries especially if you are using named queries as they underlying SQL is gener

JPA does not support Criteria queries, so if you need portability use HQL queries.

There is a difference in terms of performance between HQL and criteriaQuery, every time you fire a que
for the table name which does not reflect in the last queried cache for any DB. This leads to an overhea
time to execute, but not as much as you may think.

HQL can perform both select and non-select operations. Criteria can only select data, you can not per
queries.
HQL does not support pagination, but pagination can be achieved with Criteria.
Criteria is safe from SQL injection. HQL is vulnerable to SQL injection as your queries are either fixed o

Criteria cr = session.createCriteria(Employee.class);

// To get records having salary more than 2000

cr.add(Restrictions.gt("salary", 2000));

// To get records having salary less than 2000


cr.add(Restrictions.lt("salary", 2000));

// To get records having fistName starting with zara


cr.add(Restrictions.like("firstName", "zara%"));

// Case sensitive form of the above restriction.


cr.add(Restrictions.ilike("firstName", "zara%"));

// To get records having salary in between 1000 and 2000


cr.add(Restrictions.between("salary", 1000, 2000));

// To check if the given property is null


cr.add(Restrictions.isNull("salary"));

// To check if the given property is not null


cr.add(Restrictions.isNotNull("salary"));

// To check if the given property is empty


cr.add(Restrictions.isEmpty("salary"));

// To check if the given property is not empty


cr.add(Restrictions.isNotEmpty("salary"));

You can create AND or OR conditions using LogicalExpression restrictions as


follows:
Criteria cr = session.createCriteria(Employee.class);

Criterion salary = Restrictions.gt("salary", 2000);


Criterion name = Restrictions.ilike("firstNname","zara%");

// To get records matching with OR condistions


LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );

// To get records matching with AND condistions


LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );
List results = cr.list();

Pagination:
cr.setFirstResult(1);
cr.setMaxResults(10);

Sorting:
crit.addOrder(Order.desc("salary"));
crit.addOrder(Order.asc("salary"));

Fetching Strategies
There are four fetching strategies
1. fetch-join = Disable the lazy loading, always load all the collections and entities.
2. fetch-select (default) = Lazy load all the collections and entities.
3. batch-size=N = Fetching up to N collections or entities, *Not record*.
4. fetch-subselect = Group its collection into a sub select statement.

Fetching strategies examples

Heres a one-to-many relationship example for the fetching strategies demonstration. A


stock is belong to many stock daily records.

@Entity
@Table(name = "stock", catalog = "mkyong")
public class Stock implements Serializable{
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
@Cascade(CascadeType.ALL)
@Fetch(FetchMode.SELECT)
@BatchSize(size = 10)
public Set<StockDailyRecord> getStockDailyRecords() {
return this.stockDailyRecords;
}
...
}

1. fetch=select or @Fetch(FetchMode.SELECT)
This is the default fetching strategy. it enabled the lazy loading of all its related
collections. Let see the example
//call select from stock
Stock stock = (Stock)session.get(Stock.class, 114);

Set sets = stock.getStockDailyRecords();

//call select from stock_daily_record


for ( Iterator iter = sets.iterator();iter.hasNext(); ) {
StockDailyRecord sdr = (StockDailyRecord) iter.next();
System.out.println(sdr.getDailyRecordId());
System.out.println(sdr.getDate());
}

Hibernate Named Query


The hibernate named query is way to use any query by some meaningful name. It is like
using alias names. The Hibernate framework provides the concept of named queries so that
application programmer need not to scatter queries to all the java code.
There are two ways to define the named query in hibernate:

by annotation

by mapping file.

Hibernate Named Query by annotation


If you want to use named query in hibernate, you need to have knowledge of
@NamedQueries and @NamedQuery annotations.
@NameQueries annotation is used to define the multiple named queries.
@NameQuery annotation is used to define the single named query.
Let's see the example of using the named queries:
1.
2.
3.

@NamedQueries(
{
@NamedQuery(

4.
5.
6.
7.
8.

name = "findEmployeeByName",
query = "from Employee e where e.name = :name"
)

Example of Hibernate Named Query by annotation


In this example, we are using annotations to defined the named query in the persistent
class. There are three files only:

Employee.java

hibernate.cfg.xml

FetchDemo

In this example, we are assuming that there is em table in the database containing 4
columns id, name, job and salary and there are some records in this table.

Employee.java
It is a persistent class that uses annotations to define named query and marks this class as
entity.
package com.javatpoint;
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@NamedQueries(
{
@NamedQuery(
name = "findEmployeeByName",
query = "from Employee e where e.name = :name"
)
}
)
@Entity
@Table(name="em")
public class Employee {
public String toString(){return id+" "+name+" "+salary+" "+job;}
int id;
String name;
int salary;

String job;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
}

//getters and setters

You might also like