JPA – Second Level Cache (L2 Cache)
What problem does L2 Cache solve?

From your previous First Level Cache:
- Every HTTP request creates a new EntityManager
- Each EntityManager has its own 1st level cache
- So across requests → DB is hit every time
Without L2:
Request 1 → EM1 → DB
Request 2 → EM2 → DB
Request 3 → EM3 → DB
With L2:
All EntityManagers → Second Level Cache → DB
So now:
Multiple sessions share the same cache.
Architecture
Hibernate
↓
hibernate-cache
↓
JCache API
↓
Ehcache / Hazelcast / Caffeine
Hibernate talks to JCache, not directly to cache provider.
This gives:
- Loose coupling
- Easy provider switch
Required Dependencies
Three dependencies are mandatory:
1. Ehcache (Core)
Provides actual L2 cache implementation.
2. hibernate-jcache
Allows Hibernate to use JCache.
3. javax.cache (JCache API)
Standard caching interface.
Without all 3 → L2 cache will not work.
application.properties (Page 3)
Key configs:
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.jcache.JCacheRegionFactory
spring.cache.jcache.config=classpath:ehcache.xml
Region Concept (Very Important)
Region = logical cache group.
Used to:
- Set TTL
- Max size
- Eviction policy
- Concurrency strategy
Example:
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,
region = "userDetailsCache")
Different entities → Different regions.
ehcache.xml (Page 3)
Example:
<cache alias="userDetailsCache"
maxElementsInMemory="100"
timeToLiveSeconds="60"
evictionStrategy="FIFO"/>
CacheConcurrencyStrategy (Main Interview Topic)
1. READ_ONLY
Best for:
- Static master data
- Country list
- Bank IFSC codes
Rules:
- No updates allowed
- Update → Exception thrown
2. READ_WRITE (Page 5)
Most commonly used.
Behavior:
- Shared lock during read
- Exclusive lock during update
- Ensures strong consistency
Flow:
Read → Cache hit
Update → Lock → Update DB → Update cache
Safe for:
- Banking
- Payments
- User profiles
3. NONSTRICT_READ_WRITE (Page 6)
Fast but risky.
Behavior:
- No lock on read
- On update → cache invalidated
- May return stale data
Good for:
- Analytics dashboards
- News feeds
- High read systems
4. TRANSACTIONAL
Strongest but slowest.
Rules:
- Cache participates in DB transaction
- Full ACID consistency
Used in:
- Financial ledgers
- Core banking systems
Important Runtime Observations
Insert
- Always goes to DB
- Cache not populated
First GET
- Cache miss
- Reads from DB
- Puts into cache
Second GET
- Cache hit
- No DB call
Update
- Locks cache
- Updates DB
- Updates cache
Real System Example (SBI style)
Customer table:
- 10 million users
- 1000 requests/sec
Without L2:
→ 1000 DB hits/sec
With L2:
→ 10 DB hits/sec
Massive:
- Latency drop
- Infra cost reduction
- Stability improvement
Common Developer Mistakes
| Mistake | Reality |
|---|---|
| Cache not working | Region missing |
| DB still hit | Using new entity |
| Cache lost | Restart clears memory |
| Updates not reflected | Using READ_ONLY |
When NOT to use L2 Cache
❌ Highly volatile data
❌ Real-time trading prices
❌ Chat messages
❌ Session tokens
Interview Q&A (High Value)
Q1. Difference between L1 and L2 cache?
| L1 | L2 |
|---|---|
| Per EntityManager | Application-wide |
| Default | Manual config |
| Per request | Shared |
| Mandatory | Optional |
Q2. Does save() go to L2?
No. Insert always goes to DB first.
Q3. Can repository share L2?
Yes. All repositories across app share it.
Q4. Which is safest strategy?
TRANSACTIONAL
Q5. Which is fastest?
NONSTRICT_READ_WRITE
Q6. Why JCache?
So you can switch:
Ehcache → Hazelcast → Redis
Without code change.
One Line Summary (Perfect for Interview)
Second Level Cache is a shared, application-wide Hibernate cache that stores entity data across sessions using providers like Ehcache via JCache API, reducing repeated database access.
Mental Model (Remember this forever)
L1 Cache = Memory inside EntityManager
L2 Cache = Memory inside Application
DB = Permanent storage
Production Advice (From Experience)
For Spring Boot microservices:
| Data Type | Strategy |
|---|---|
| Master Data | READ_ONLY |
| User Data | READ_WRITE |
| Analytics | NONSTRICT |
| Banking | TRANSACTIONAL |