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.
Additions/corrections:
This cache is delegated to a specialized cache provider, such as Infinispan or EhCache. So, eviction is configured/requested by you, but performed by the cache provider.
You need to explicitly tell Hibernate which entities you want to cache.
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. There are, of course, cache invalidation techniques, such as "invalidate the cache if table X was touched by this update", so that the cache doesn't gets stale.
Isolation Level Cache
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.
Session Level (1st-Level) Cache
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. Callingevict()
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 aflush()
is to commit the transaction.2nd-Level Cache
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 andgetCache().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:
Query Cache
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.