Caching Levels Overview

Why Cache at All

Every trip to the database costs network time, CPU on the database server and a connection from the pool. ShopEase shows the same category list and the same top products to thousands of users. Reading them again and again from MySQL is wasted work.

Hibernate has three caches. They live at different places and have very different lifetimes:

CacheScopeEnabled by defaultStores
First-level (L1)one EntityManager / Session (usually one transaction)Yes, always onmanaged entity objects
Second-level (L2)the whole EntityManagerFactory (all sessions, one JVM or a cluster)Noentity data in "dehydrated" form (arrays of column values)
Query cachethe whole EntityManagerFactoryNoquery + parameters → list of entity ids

Where Each Cache Sits

HTTP request ──► Service (@Transactional)
                     │
                     ▼
            ┌──────────────────────┐
            │ Session / EM         │  first-level cache (per transaction)
            │  Map<id, entity>     │
            └─────────┬────────────┘
                      │ miss
                      ▼
            ┌──────────────────────┐
            │ SessionFactory       │  second-level cache + query cache
            │  (shared by all)     │  (Caffeine / Ehcache / Infinispan / Redis via JCache)
            └─────────┬────────────┘
                      │ miss
                      ▼
               MySQL / PostgreSQL

Note: Lookups go top to bottom: L1 first, then L2, then the database. A cache only helps for reads by id (L1, L2) or for the exact same query with the same parameters (query cache).