Working with a query cache

Hibernate supports a useful feature that actually helps to improve the performance of the application by reducing the processing time. The feature we are talking about here is called query cache.

Hibernate caches the query result, which is frequently used. This feature is only useful if the same queries are executed frequently.

Getting ready

To understand the query cache, we will use the Employee POJO that was created in the previous recipe entitled Working with a first-level cache. We also need to modify hibernate.cfg.xml to enable the query cache feature:

Source file: Employee.java

@Entity
public class Employee {

  @Id
  @GeneratedValue
  private long id;

  @Column(name = "name")
  private String name;
  
  // getters and setters

}

Enabling a query cache:

To use this feature, we will first need to enable the query cache by adding the following tag in the configuration file:

<property name="hibernate.cache.use_query_cache">true</property>

How to do it…

Here, we will create an executable class to see how the query cache works. The following code shows the same:

Session session = sessionFactory.openSession();
for (int i = 0; i < 5; i++) {
    /* Line 3 */ Criteria criteria = session.createCriteria(Employee.class).setCacheable(true);
    List<Employee> employees = criteria.list();
    System.out.println("Employees found: " + employees.size());
}
session.close();

The following is the output for the preceding code:

Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from employee this_
Employees found: 1
Employees found: 1
Employees found: 1
Employees found: 1
Employees found: 1

How it works…

In the preceding code, we executed the same query five times using a loop. This means that the query should hit the database five times in order to search. But as shown in output, it hits the database only once and from the second time onward, hibernate checks whether this particular query is cached or not. If the query is found in the cache, it just displays the output; if it's not found in the cache, it first adds it to cache and executes it against the database and then displays the result.

From the output, it looks similar to the first-level cache, but there is actually a difference between the two of them. The query cache checks whether a particular query is cached or not and the first-level cache checks the object in this particular cache. An invocation of the list() method always hits the database even if the first-level cache is enabled.

As shown in Line 3, we used the setCachable(true) method. Once we set cachable to true, it tells hibernate to cache the particular query.

There's more...

Let's take a look at what happens if we ignore the setCachable(…) method. Consider the following code:

Code

Session session = sessionFactory.openSession();
for (int i = 0; i < 5; i++) {
  /* Line 3 */ Criteria criteria = session.createCriteria(Employee.class);
  List<Employee> employees = criteria.list();
  System.out.println("Employees found: " + employees.size());
}
session.close();

Output

Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from employee this_
Employees found: 1
Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from employee this_
Employees found: 1
Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from employee this_
Employees found: 1
Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from employee this_
Employees found: 1
Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from employee this_
Employees found: 1

From the output, it's clear that if we don't set setcachable to true, hibernate will not cache our query, and the query will hit the database every time the loop iterates. This is not a feasible option as it may downgrade the performance.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.89.18