JPA – Second Level Cache (L2 Cache)

 


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

 

Leave a Reply