✅ What’s the difference between query cache and first-level cache in Hibernate?
🔹 First-Level Cache
✅ Scope: Limited to a single Hibernate Session
.
✅ Enabled: Always on — cannot be disabled.
✅ Purpose: Caches individual entity instances you load, save, or update in the current session → avoids repeated DB queries for the same entity within that session.
✅ Behavior: Once a session is closed, the first-level cache is destroyed.
✅ Granularity: Works on per-entity basis — not on query results.
Example:
User user1 = session.get(User.class, 1L); // SQL query sent
User user2 = session.get(User.class, 1L); // Served from first-level cache
🔹 Query Cache
✅ Scope: Shared across sessions → tied to the second-level cache and the SessionFactory
.
✅ Enabled: Optional — disabled by default, must be explicitly enabled with hibernate.cache.use_query_cache=true
.
✅ Purpose: Caches results of specific HQL/Criteria queries, so identical queries can reuse cached results without re-executing SQL.
✅ Behavior: Caches the IDs of the result list; actual entity data must also be in the second-level cache for a full cache hit.
✅ Granularity: Works on entire query results, not individual entities.
Example:
List<User> users = session.createQuery("FROM User WHERE active = true")
.setCacheable(true)
.list(); // first call hits DB, later identical calls hit query cache
🔹 Key differences summarized:
Feature | First-Level Cache | Query Cache |
---|---|---|
Scope | Single Session | Across sessions (SessionFactory scope) |
Enabled by default | Always | Must enable + mark queries cacheable |
What it caches | Individual entity instances | Result lists (IDs) for specific queries |
Usage | Every CRUD operation | Optimizing repeated identical read queries |
Lifetime | Until session is closed | Until evicted or invalidated |
✅ Key takeaway:
- First-level cache: always-on, session-scoped, caches individual entities → avoids duplicate queries within the same session.
- Query cache: optional, shared across sessions, caches result sets of identical queries → avoids database hits across sessions.