Professional Documents
Culture Documents
SessionFactory
Session (interface):
SessionImpl implements Session.
detached: Once we close the Hibernate Session, the persistent instance will
become a detached instance.
Transaction :
Transaction interface that defines the unit of work. It maintains abstraction from
the transaction implementation of JTA/Jdbc.
Syntax:
Transaction tx = session.beginTransaction();
Query and Criteria :
Syntax:
Query query = session.createQuery("from Employee e where e.empid = 100");
Criteria criteria =
session.createCriteria(Employee.class).add(Restrictions.eq("empid", 100));
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.
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() :
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.
2.
3.
4.
5.
6.
B.
C.
D.
E.
F.
G.
H.
I.
J.
database independent
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.
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();
1.
2.
3.
4.
5.
Query q = session
.createQuery("from MyObject n where n.state = 'NEW'")
.setLockOptions(new LockOptions(LockMode.PESSIMISTIC_WRITE));
List<MyObject> list = (List<MyObject>) q.list();
batch processing.
.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());
}
@NamedNativeQueries({
@NamedNativeQuery(
name = "callStockStoreProcedure",
query = "CALL GetStocks(:stockCode)",
resultClass = Stock.class
)
})
@Entity
@Table(name = "stock")
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);
cr.add(Restrictions.gt("salary", 2000));
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.
@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);
by annotation
by mapping file.
@NamedQueries(
{
@NamedQuery(
4.
5.
6.
7.
8.
name = "findEmployeeByName",
query = "from Employee e where e.name = :name"
)
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)
}