I'm looking for a simple, complete, concise listing of the caches you will run into coding JPA with Hibernate.
In particular I'd like to know for each cache, the lifecycle of the cache (when does the cache go stale), the scope of the cache, ways to clear the cache (if any), what gets cached, if the cache is on by default, how to turn it on/off, and any useful information.
I tried finding this information in another question but couldn't find any complete answers. The answers are also spread across the Hibernate documentation but I've had a hard time finding them there too.
I plan to answer this question myself as a community wiki to get the ball rolling but I still don't know all the answers so there will be some holes to fill in.
By default, Hibernate only uses per-session (L1) cache, so, objects, cached in one session, are not seen in another. However, an L2 cache may be used, in which the cached objects are seen for all sessions that use the same L2 cache configuration.
Hibernate Cache can be very useful in gaining fast application performance if used correctly. The idea behind cache is to reduce the number of database queries, hence reducing the throughput time of the application.
Hibernate also implements a cache for query resultsets 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.
You can enable Hibernate statistics generation be setting hibernate. generate_statistics property to true . Then you can monitor cache hit/miss count via SessionFactory. getStatistics() .
Summary: This cache is sometimes not really called a cache. However, in order to implement certain isolation levels the database itself may be caching some query results.
Lifecycle/Scope: This cache is scoped to a single Session/EntityManager. The lifecycle is bound to the transaction lifecycle.
Clearing the cache: No way I know of other than starting a new transaction
What gets cached: Queries and result (if isolation is at repeatable read or serializable level)
On by default: Depends on the default isolation level which comes from the database. By default, MySQL ships with repeatable read isolation and so yes, this is on by default for MySQL.
Turning it on/off: Can be specified when creating the transaction. Can also be changed by changing the default on the database.
Useful Information: Hibernate/JPA doesn't really have any control over the operation of this cache other than specifying which isolation level is desired.
Summary: This cache is the EntityManager/Session cache. I believe this is also what is referred to as the persistence context.
Lifecycle/Scope: This cache is scoped to a single Session/EntityManager. The lifecycle is bound to the transaction lifecycle.
Clearing the cache: Calling clear()
on the EntityManager or Session clears the entire cache. Calling evict()
on the Session clears a single object from the cache.
What gets cached: Everything
On by default: Yes
Turning it on/off: Can't be turned off
Useful Information: This cache gets merged with the database whenever flush()
is called. Unless that happens other transactions will not be able to see things in this cache. The best way to guarantee a flush()
is to commit the transaction.
Summary: This is a secondary cache that can be enabled (usually to try and improve performance).
Lifecycle/Scope: I believe this is bound to the EntityManagerFactory/SessionFactory. Automatic eviction of this cache depends on the cache strategy. In a read-only strategy data is never evicted automatically. In a read-write or nostrict read-write strategy data will be evicted when the session closes. Not 100% certain of this.
Clearing the cache: You can call getCache().evict(class)
to evict a specific class and getCache().evictAll()
to evict the entire cache. These methods are on the EntityManagerFactory.
What gets cached: You explicitly configure which entities should be cached.
On by default: No
Turning it on/off: Turned on/off in the Hibernate configuration
Useful Information:
Summary: Query Cache is a cache which stores queries, query parameters and results. If the query and query parameters are the same, you can expect the result to be the same.
Lifecycle/Scope: I have no idea when data in this cache is determined to be stale. I believe the scope is at the EntityManagerFactory/SessionFactory level. In addition, Hibernate keeps a list of "last update by Hibernate" timestamps for each of the tables. Hibernate uses these timestamps to determine if query results are stale and evict stale queries automatically.
Clearing the cache: The evictQueries()
method on the SessionFactory can be used to manually evict the query cache.
What gets cached: Queries and their results
On by default: No
Turning it on/off: Turned on/off in the Hibernate configuration
Useful Information: The query cache only caches entity IDs. It must be used in conjunction with a 2nd-level cache to achieve a true (no DB access) cache.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With