Query caching is one of the important features provided by Hibernate. I have explained the first level and second level caching in my previous article ( First level caching using hibernate, Second level caching ) ,When we need a particular query result has to be cached for future reference we can use query caching,
Let’s see how to configure query caching.
hibernate.cfg.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?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> <!-- Database connection settings --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/test</property> <property name="connection.username">root</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.MySQLDialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- Second-level cache --> <property name="cache.use_query_cache">true</property> <property name="cache.use_second_level_cache">true</property> <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <property name="hbm2ddl.auto">validate</property> <mapping/> </session-factory> </hibernate-configuration> |
Here we are adding the following lines to use query caching.
1 2 3 |
<property name="cache.use_query_cache">true</property> <property name="cache.use_second_level_cache">true</property> <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> |
Entity class settings
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package com.j2eereference.hibernate.queryCaching; import javax.persistence.Cacheable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Cacheable @Cache(usage = CacheConcurrencyStrategy.READ_ONLY) @Table(name = "employee") public class Employee { private int emp_id; private String emp_name; @Id @GeneratedValue @Column(name = "emp_id") public int getEmp_id() { return emp_id; } public void setEmp_id(int emp_id) { this.emp_id = emp_id; } @Column(name = "emp_name") public String getEmp_name() { return emp_name; } public void setEmp_name(String emp_name) { this.emp_name = emp_name; } } |
We have to tell hibernate that a particular query result has to be set in the cache for future use. We can do this configuration as below .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package com.j2eereference.hibernate.queryCaching; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; public class QueryCache { public static void main(String[] args) { AnnotationConfiguration config = new AnnotationConfiguration(); config.addAnnotatedClass(Employee.class); SessionFactory sessionFactory = config.configure() .buildSessionFactory(); Session session = sessionFactory.openSession(); session.beginTransaction(); Query query = session .createQuery("from Employee emp where emp.emp_id=1"); query.setCacheable(true); List employees = query.list(); session.getTransaction().commit(); Session session2 = sessionFactory.openSession(); session2.beginTransaction(); Query query2 = session2 .createQuery("from Employee emp where emp.emp_id=1"); query2.setCacheable(true); List employees2 = query2.list(); session2.getTransaction().commit(); } } |
Output
1 2 3 4 5 6 |
Oct 16, 2012 8:49:30 PM org.hibernate.cache.StandardQueryCache INFO: starting query cache at region: org.hibernate.cache.StandardQueryCache Oct 16, 2012 8:49:30 PM org.hibernate.cache.EhCacheProvider buildCache WARNING: Could not find configuration [org.hibernate.cache.StandardQueryCache]; using defaults. Hibernate: select employee0_.emp_id as emp1_0_, employee0_.emp_name as emp2_0_ from employee employee0_ where employee0_.emp_id=1 |
Here you can notice that hibernate has hit the DB only once . The second result is fetching from the cache.
setCacheable method is performing two roles.
- If querycache is not already having the value, go to the database get the result, set the queryCache
- For getting the queryCache without hitting the DB
Now lets see how the QueryCache is working with the below code .
I have explained the first level caching in my previous article ( First level caching using hibernate )
Leave a Reply