Sizing the JPA cache
Like all cases where objects are reused, the JPA cache has a potential performance downside:
if the cache consumes too much memory, it will cause GC pressure. This may require that
the cache be tuned to adjust its size, or that you control the mode in which entities remain
cached. Unfortunately, these are not standard options, so you must perform these tunings
based on which JPA provider you are using.
JPA implementations typically provide an option to set the size of the cache, either globally
or on a per-entity basis. The latter case is obviously more flexible, though it also requires
more work to determine the optimal size for each entity. An alternative approach is for the
JPA implementation to use soft and/or weak references for the L2 cache. EclipseLink, for ex-
ample, provides five different cache types (plus additional deprecated types) based on differ-
ent combinations of soft and weak references. That approach, while potentially easier than
finding optimal sizes for each entity, still requires some planning: in particular, recall from
Chapter 7 that weak references do not really survive any GC operation and are hence a ques-
tionable choice for a cache.
If a cache based on soft or weak references is used, the performance of the application will
also depend on what else happens in the heap. The examples of this section all used a large
heap so that caching the 200,448 entity objects in the application would not cause issues with
the garbage collector. Tuning a heap when there are large JPA L2 caches is quite important
for good performance.
1. The JPA L2 cache will automatically cache entities for an application.
2. The L2 cache does not cache entities retrieved via queries. This means that in the
long run it can be beneficial to avoid queries altogether.
3. Unless query caching is supported by the JPA implementation in use, using a JOIN
query turns out to frequently have a negative performance effect, since it bypasses
the L2 cache.