Search This Blog

Loading...

Wednesday, August 21, 2013

JPA2: Forcing JPA "Query" to get fresh data Rather Than Cached data.

Problem

The default behavior of EntityManager is using cached results from a database query, and you want to force a query to be executed each time a table is loaded, rather than allowing the results of the cache to be displayed.

Especially when you are working with database stored procedures, which changes the data on database server, but when you query this data, cached one is displayed, instead of new changed data.

There was a solutions by
  1. Disabling the cache from persistence.xml or

  2. Calling EntityManagerFactory.getCache().evictAll(); method in an Interceptor, I was using this solution.

Nevertheless, these solutions works but with problem, which is the performance and bandwidth is hurt, because you load all fresh and read only data such as lookups and configuration data, from database to application.

But I need to get a fresh data instead of cached ones but for specific query, so let's dive into the solution.

Solution
After the javax.persistence.Query instance is created, set a hint, javax.persistence.cache.retrieveMode, to bypass the cache and force the query to be executed. In the following lines of code, the Book entity is queried, and the cache is bypassed by setting the hint:

Upon execution, the query will be forced to execute, returning the most current results from the underlying database table.

Working mechanism
There are often occasions when an application requires the most current table data to be displayed or used for performing a given task. For instance, if you were to write a Stock Exchange application, it would not make sense to cache the current stock results since old data would not be very useful to investors.

In such cases, it is imperative to force queries to be executed and bypass any caching. This is possible via the use of hints that can be registered with javax.persistence.Query instances.

By setting the javax.persistence.cache.retrieveMode hint to CacheRetrieveMode.BYPASS, the JPA is told to always force the execution of a query. When the query is executed, it will always return the most current results from the database.

References:
More on cache disabling mechanisms could be fund on Java EE 6 Tutorial Specifying the Cache Mode Settings to Improve Performance