In this tutorial, we'll learn about Hibernate's cache
support: both first level (Session) and second level cache.
Good tutorials
Hibernate uses two
different caches for objects: first-level cache and second-level cache.
1.1) First-level cache :
First-level cache always Associates with the Session
object. Hibernate uses this cache by default. Here, it processes one
transaction after another one, means wont process one transaction many times.
Mainly it reduces the number of SQL queries it needs to generate within
a given transaction. That is instead of updating after every modification done
in the transaction, it updates the transaction only at the end of the
transaction.
1.2) Second-level cache :
Second-level cache always associates with the Session
Factory object. While running the transactions, in between it loads the
objects at the Session Factory level, so that those objects will
available to the entire application, don’t bounds to single user. Since the
objects are already loaded in the cache, whenever an object is returned by the
query, at that time no need to go for a database transaction. In this way the
second level cache works. Here we can use query level cache also. Later
we will discuss about it.
2) Cache Implementations
Hibernate
supports four open-source cache
implementations named
1. EHCache (Easy Hibernate Cache)
2. OSCache (Open Symphony Cache)
3. Swarm Cache,
and
4. JBoss Tree Cache.
Each
cache has different performance, memory use, and configuration possibilities.
First level cache - Session
Second level Cache
- Across
sessions in an application
- Across
applications
- Across clusters
If you call below statements only one call goes to DB
UserDetails user=(UserDetails)session.get(UserDetails.class, 1);
UserDetails user2=(UserDetails)session.get(UserDetails.class, 1);
/**********************************************/
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user=(UserDetails)session.get(UserDetails.class, 1);
session.getTransaction().commit();
session.close();
Session session2 = sessionFactory.openSession();
session2.beginTransaction();
UserDetails user2=(UserDetails)session2.get(UserDetails.class,
11);
session2.getTransaction().commit();
session2.close();
If we run above code it will two select queries because if session
close than cache also close. In this scenario we require second level cache so
that second query should come from cache, if record doent match then hit the
query to database.
/**********************************************/
HibernateTest.java
package org.yash.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.yash.dto.UserDetails;
public class HibernateTest {
public static void main(String
args[]) {
SessionFactory
sessionFactory = new Configuration().configure()
.buildSessionFactory();
Session session =
sessionFactory.openSession();
session.beginTransaction();
UserDetails user=(UserDetails)session.get(UserDetails.class, 11);
session.getTransaction().commit();
session.close();
session =
sessionFactory.openSession();
session.beginTransaction();
UserDetails user2=(UserDetails)session.get(UserDetails.class, 11);
session.getTransaction().commit();
session.close();
}
}
UserDetails.java
package org.yash.dto;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
@Entity
@NamedQuery(name="UserDetails.byId", query="from
UserDetails where userId = ?") //HQL query - based on class name
@org.hibernate.annotations.Entity(selectBeforeUpdate=true)
public class UserDetails {
/* @Id says
"userId" is primary key */
@Id @GeneratedValue
(strategy=GenerationType.AUTO)
private int userId;
private String userName;
@OneToMany(cascade=CascadeType.PERSIST)
private
Collection<Vehicle> vehicle = new
ArrayList<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;
}
public void
setVehicle(Collection<Vehicle> vehicle) {
this.vehicle = vehicle;
}
public
Collection<Vehicle> getVehicle() {
return vehicle;
}
}
hibernate.cfg.xml
<?xml
version='1.0' encoding='utf-8'?>
<!DOCTYPE
hibernate-configuration PUBLIC
"-//Hibernate/Hibernate
Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">
org.postgresql.Driver
</property>
<property name="connection.url">
jdbc:postgresql://localhost:5433/hibernatedb
</property>
<property name="connection.username">postgres</property>
<property name="connection.password">admin</property>
<!-- JDBC
connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL
dialect -->
<property name="dialect">
org.hibernate.dialect.PostgreSQLDialect
</property>
<!-- Enable
Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</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>
<!-- create /
update -->
<!-- Names the annotated entity
class -->
<mapping class="org.yash.dto.UserDetails"/>
</session-factory>
</hibernate-configuration>
Happy to found this blog. Good Post!. It was so good to read and useful to improve my knowledge as updated one, keep blogging. Hibernate Training in Electronic City
ReplyDeleteJava Training in Electronic City