Query-level Cache

  • Hibernate also implements a cache for query result sets that integrates closely with the second-level cache.
  • This is an optional feature and requires two additional physical cache regions that hold the cached query results and the timestamps when a table was last updated.
  • This is only useful for queries that are run frequently with the same parameters.

Example of Query-level Cache

  • You need to download and add ehcache-core-2.4.2 jar into your classpath.
  • Add property 'cache.use_query_cache' in to hibernate.cfg.xml file and give 'true' as value to enable query level cache.
  • Add property 'cache.provider_class' into hibernate.cfg.xml file and give 'org.hibernate.cache.EhCacheProvider' as value

hibernate.cfg.xml file
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
   <property name="hibernate.dialect"> 
   	org.hibernate.dialect.MySQLDialect </property>
   <property name="hibernate.connection.driver_class"> 
   	com.mysql.jdbc.Driver </property>

   <!-- Assume hibernatedb as the database name -->
   <property name="hibernate.connection.url"> 
   	jdbc:mysql://localhost/hibernatedb </property>
   <property name="hibernate.connection.username"> 
   	root </property>
   <property name="hibernate.connection.password"> 
   	root </property>
   
	<!-- Enable the second-level cache,
		here EhCache is used for caching-->
   <property name="cache.use_second_level_cache">
   	true
   </property>
   <property name="cache.use_query_cache">true</propery>
   <property name="cache.provider_class">
   	org.hibernate.cache.EhCacheProvider</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>	
   
   <!-- Names the annotated entity class -->
    <mapping class="com.tkhts.Student"/>

   </session-factory>
</hibernate-configuration>
Student.java file
package com.tkhts;

import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Cacheable //this annotation is use for enabling cache
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY) 
//this annotation is use to
//define Cache Concurrency Strategy

@Table(name="STUDENT")
public class Student {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
Test.java file
package com.tkhts.test;

import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.tkhts.Student;

public class Test {
	
	public static void main(String[] args) {
		SessionFactory sessionFactory = new
		Configuration().configure()
		.buildSessionFactory();
		
		/*creating first session object */
		Session session=sessionFactory.openSession();
		session.beginTransaction();
		
		Query query1 = session.createQuery
			("from Student student where student.id=1");
		query1.setCacheable(true); 
		//setting query to be cacheable
		
		List list1=query1.list();
		session.getTransaction().commit();
		session.close(); //first session object closed
		
		/*creating second session object*/
		Session session2=sessionFactory.openSession();
		session2.beginTransaction();
		Query query2 = session2.createQuery
			("from Student student where student.id=1");
			
		query2.setCacheable(true);
			//setting query to be cacheable
		List list2=query2.list();
		session2.getTransaction().commit();
		session2.close();
			//second session object closed
		}
}
Output On console
SLF4J: Failed to load class
		"org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation
		(NOP) logger implementation
SLF4J: See
	http://www.slf4j.org/codes.php#StaticLoggerBinder 
	for further details.
	Hibernate: select student0_.id
	as id0_, student0_.name as 
	name0_ from STUDENT student0_
	where student0_.id=1