Hibernate First-Level Cache Interview Questions and Answers

Master Hibernate First-Level Cache with production-ready interview questions covering persistence context, Session scope, identity guarantee, find behavior, evict, clear, flush, memory usage, dirty checking, and senior-level best practices.


Introduction

Hibernate's First-Level Cache is one of the most important parts of the persistence context.

It is enabled automatically and stores managed entity instances within a Hibernate Session or JPA EntityManager.

When the same entity is requested multiple times inside one persistence context, Hibernate can return the already managed object instead of executing another database query.

The First-Level Cache supports:

  • Entity identity
  • Dirty checking
  • Write-behind behavior
  • Reduced duplicate queries
  • Persistence-context consistency
  • Transactional entity tracking

Although the First-Level Cache improves performance, keeping too many entities managed can increase memory usage and dirty-checking overhead.

Understanding its scope and behavior is essential for diagnosing:

  • Unexpected SQL queries
  • Stale managed data
  • Memory problems
  • Batch-processing slowdowns
  • Entity lifecycle issues
  • Dirty-checking behavior

This guide covers the 15 most frequently asked Hibernate First-Level Cache interview questions with code examples, diagrams, production scenarios, common mistakes, and senior-level best practices.


Q1. What is Hibernate First-Level Cache?

Answer

The First-Level Cache is a mandatory, in-memory cache associated with a Hibernate Session or JPA persistence context.

It stores managed entity instances by their entity type and identifier.

When Hibernate loads an entity, it places that entity in the persistence context.

If the same entity is requested again within the same persistence context, Hibernate usually returns the cached managed instance instead of querying the database again.

Example

Customer first =
    entityManager.find(Customer.class, 101L);

Customer second =
    entityManager.find(Customer.class, 101L);

Hibernate generally executes one SELECT.

Both variables refer to the same managed object:

System.out.println(first == second);

Output:

true

Flow

flowchart TD

A["find(Customer,101)"]

A --> B["First-Level Cache"]

B -->|Miss| C["SELECT Customer"]

C --> D["Managed Customer"]

D --> E["Store in Persistence Context"]

E --> F["Return first"]

F --> G["find(Customer,101)"]

G --> B

B -->|Hit| H["Return Same Managed Object"]

H --> I["first == second → true"]

H --> J["No Additional SELECT"]

Why Interviewers Ask This

The First-Level Cache explains how Hibernate maintains entity identity, dirty checking, and repeated retrieval behavior.

Production Example

A service method loads the same account through multiple repository operations within one transaction. Hibernate may reuse the already managed entity.

Common Mistake

Thinking First-Level Cache is shared across the entire application.

Senior Follow-up

The First-Level Cache is scoped to one persistence context, not to the whole application.


Q2. Is First-Level Cache enabled by default?

Answer

Yes.

Hibernate First-Level Cache is always enabled for every Session.

In JPA, the persistence context maintained by an EntityManager provides equivalent behavior.

It is an essential part of Hibernate's entity management model and cannot normally be disabled.

Why It Is Mandatory

Hibernate depends on the persistence context for:

  • Managed entity identity
  • Dirty checking
  • Cascading
  • Transactional write-behind
  • Relationship synchronization
  • Change tracking

Example

try (Session session = sessionFactory.openSession()) {

    Customer customer =
        session.find(Customer.class, 101L);
}

The loaded entity is stored automatically in that session's First-Level Cache.

Common Mistake

Looking for a Hibernate property to enable First-Level Cache.

No special configuration is required.

Senior Follow-up

You can reduce its impact using detach(), evict(), clear(), read-only queries, stateless sessions, or DTO projections, but the normal persistence context itself includes First-Level Cache behavior.


Q3. What is the scope of First-Level Cache?

Answer

The First-Level Cache is scoped to one Hibernate Session or JPA persistence context.

It is not shared between:

  • Different sessions
  • Different entity managers
  • Different transactions using separate persistence contexts
  • Different application instances

Example

try (Session firstSession =
         sessionFactory.openSession()) {

    firstSession.find(Customer.class, 101L);
}
try (Session secondSession =
         sessionFactory.openSession()) {

    secondSession.find(Customer.class, 101L);
}

Each session has its own First-Level Cache.

Hibernate may execute one query in each session.

Scope Diagram

Session A
│
└── First-Level Cache
    └── Customer#101

Session B
│
└── First-Level Cache
    └── Separate Customer#101 Instance

Production Example

Two concurrent HTTP requests typically use separate persistence contexts and therefore separate First-Level Caches.

Common Mistake

Assuming one request can reuse another request's First-Level Cache.

Senior Follow-up

Cross-session caching requires Second-Level Cache or an application-level caching strategy.


Q4. How does Session caching work?

Answer

Hibernate stores managed entities using a logical key containing:

  • Entity type
  • Entity identifier

Conceptually:

EntityKey
├── Entity Name: Customer
└── Identifier: 101

The corresponding value is the managed entity instance.

Simplified Cache View

First-Level Cache
│
├── Customer#101 → Customer Object
├── Customer#102 → Customer Object
└── Order#5001   → Order Object

When Hibernate resolves an entity:

  1. Check the persistence context.
  2. Return the managed instance if found.
  3. Otherwise check other configured caching layers where applicable.
  4. Query the database if needed.
  5. Store the result as a managed entity.

Example

Customer customer =
    session.find(Customer.class, 101L);

After this call, Customer#101 is managed by that session.

Common Mistake

Thinking the cache stores raw SQL result sets.

It stores entity instances and associated persistence metadata.

Senior Follow-up

Hibernate also tracks snapshots or enhancement-based change information to support dirty checking.


Q5. What happens when the same entity is fetched twice?

Answer

Within the same persistence context, Hibernate returns the same managed entity instance.

Example

Customer first =
    entityManager.find(Customer.class, 101L);

Customer second =
    entityManager.find(Customer.class, 101L);

System.out.println(first == second);

Output:

true

Expected SQL

SELECT
    c.id,
    c.name,
    c.email
FROM customers c
WHERE c.id = ?

This query generally executes only once.

Why the Same Instance Matters

This identity guarantee prevents conflicting in-memory representations of the same database row.

Without it:

Customer Object A → ID 101 → email A

Customer Object B → ID 101 → email B

Hibernate would not know which state should be written.

With the persistence context:

Customer#101 → One Managed Object

Production Example

Multiple repository methods can retrieve the same entity during one transaction while Hibernate maintains one consistent managed instance.

Common Mistake

Assuming a second find() always refreshes data from the database.

Senior Follow-up

Use refresh() when the managed entity must be reloaded from the database.


Q6. What is the difference between First-Level Cache and Persistence Context?

Answer

The terms are closely related but not completely identical.

The Persistence Context is the broader entity-management environment.

The First-Level Cache is one capability within that environment.

Persistence Context Responsibilities

  • Stores managed entities
  • Maintains identity
  • Tracks entity state
  • Supports dirty checking
  • Coordinates cascading
  • Tracks scheduled inserts, updates, and deletes
  • Synchronizes changes during flush

First-Level Cache Responsibility

  • Reuses managed entity instances by identifier
  • Avoids repeated entity loading within one persistence context

Relationship

Persistence Context
│
├── First-Level Cache
├── Entity Snapshots
├── Dirty Checking
├── Insert Queue
├── Update Queue
├── Delete Queue
└── Relationship Tracking

Interview Tip

A strong answer is:

The First-Level Cache is the identity map inside the persistence context, while the persistence context also manages lifecycle, dirty checking, and synchronization.

Common Mistake

Using the terms as though the persistence context performs only caching.


Q7. How do evict() and clear() affect First-Level Cache?

Answer

Both operations remove managed entities from the First-Level Cache.

evict()

Hibernate-native evict() removes one entity from the session.

Customer customer =
    session.find(Customer.class, 101L);

session.evict(customer);

The entity becomes detached.

JPA Equivalent

entityManager.detach(customer);

clear()

clear() removes every managed entity from the persistence context.

entityManager.clear();

All managed entities become detached.

Comparison

Operation Effect
evict(entity) Removes one entity
detach(entity) JPA equivalent for one entity
clear() Removes all managed entities
close() Ends the persistence context

Flow

First-Level Cache
│
├── Customer#101
├── Customer#102
└── Order#5001

After:

session.evict(customer101);
First-Level Cache
│
├── Customer#102
└── Order#5001

After:

session.clear();
First-Level Cache
│
└── Empty

Common Mistake

Calling clear() before flush() and losing pending managed changes from the context.

Senior Follow-up

During batch processing, use flush() followed by clear() at controlled intervals.


Q8. What happens to First-Level Cache after a transaction completes?

Answer

The exact behavior depends on the persistence-context scope.

In common transaction-scoped applications:

  1. Transaction begins.
  2. Persistence context is created or joined.
  3. Entities become managed.
  4. Transaction commits or rolls back.
  5. Persistence context closes.
  6. Managed entities become detached.
  7. First-Level Cache is discarded.

Common Spring Transaction Flow

sequenceDiagram
participant Controller
participant Service
participant EntityManager
participant Database
Controller->>Service: HTTP Request
Service->>EntityManager: Begin Transaction
EntityManager->>Database: Load Entity
Database-->>EntityManager: Managed Entity
Service->>Service: Business Logic
Service->>EntityManager: Commit
EntityManager->>EntityManager: Dirty Checking
EntityManager->>Database: UPDATE SQL
Database-->>EntityManager: Success
EntityManager-->>Controller: Transaction Complete

Important Nuance

A transaction and persistence context are related but not always identical.

Extended persistence contexts can survive across multiple transactions.

Production Example

A typical Spring Boot service method annotated with @Transactional uses one persistence context for the duration of that transaction.

Common Mistake

Assuming cached entities remain managed after the transaction ends.

Senior Follow-up

Returning entities outside the service layer often exposes detached objects and lazy-loading risks.


Q9. Can First-Level Cache be disabled?

Answer

Not in a normal Hibernate Session.

The First-Level Cache is integral to Hibernate's persistence context and entity-management model.

However, developers can avoid retaining managed entities through other approaches.

Alternatives

Detach a Specific Entity

entityManager.detach(customer);

Clear the Entire Persistence Context

entityManager.clear();

Use DTO Projections

select new com.codewithvenu.CustomerSummary(
    c.id,
    c.name
)
from Customer c

DTOs are not managed entities.

Use Read-Only Query Settings

query.setHint(
    "org.hibernate.readOnly",
    true
);

Use StatelessSession

try (StatelessSession session =
         sessionFactory.openStatelessSession()) {

    Customer customer =
        session.get(Customer.class, 101L);
}

A StatelessSession does not provide normal persistence-context behavior such as:

  • First-Level Cache
  • Automatic dirty checking
  • Cascading
  • Normal lifecycle management

Common Mistake

Using StatelessSession without understanding its reduced ORM behavior.

Senior Follow-up

For high-volume streaming or batch operations, StatelessSession may be appropriate when normal entity tracking is unnecessary.


Q10. How does dirty checking use First-Level Cache?

Answer

Dirty checking relies on managed entities stored in the persistence context.

When Hibernate loads an entity, it tracks its original state.

At flush time, Hibernate compares the entity's current state with its original state.

Example

@Transactional
public void updateEmail(
    Long customerId,
    String email
) {

    Customer customer =
        entityManager.find(
            Customer.class,
            customerId
        );

    customer.setEmail(email);
}

No explicit update call is needed.

Dirty Checking Flow

sequenceDiagram
participant Application
participant Hibernate
participant Database
Application->>Hibernate: Load entity
Hibernate->>Database: SELECT
Database-->>Hibernate: Entity data
Hibernate->>Hibernate: Store managed entity
Hibernate->>Hibernate: Store original snapshot
Hibernate-->>Application: Return managed entity
Application->>Application: Modify entity field
Application->>Hibernate: Flush / commit
Hibernate->>Hibernate: Compare current state<br/>with original state
alt Entity changed
    Hibernate->>Database: Execute UPDATE
    Database-->>Hibernate: Success
else Entity unchanged
    Hibernate->>Hibernate: No UPDATE required
end

Why Cache and Dirty Checking Are Connected

The persistence context must retain:

  • The managed object
  • Entity metadata
  • Original state or change-tracking information

Without this state, Hibernate could not detect changes automatically.

Common Mistake

Assuming dirty checking occurs for detached entities.

Senior Follow-up

A large First-Level Cache means Hibernate must manage more entity state, increasing flush and dirty-checking overhead.


Q11. How does First-Level Cache affect memory usage?

Answer

Every managed entity remains referenced by the persistence context until it is:

  • Detached
  • Evicted
  • Cleared
  • Removed and synchronized
  • Persistence context is closed

Loading a large number of entities into one session can therefore consume significant memory.

Problem Example

@Transactional
public void importCustomers(
    List<Customer> customers
) {

    for (Customer customer : customers) {
        entityManager.persist(customer);
    }
}

If the list contains one million entities, the persistence context may retain all of them until the transaction completes.

Risks

  • High heap usage
  • Increased garbage collection
  • Slow dirty checking
  • Longer flush time
  • OutOfMemoryError
  • Reduced throughput

Improved Batch Pattern

@Transactional
public void importCustomers(
    List<Customer> customers
) {

    int batchSize = 1000;

    for (int index = 0;
         index < customers.size();
         index++) {

        entityManager.persist(
            customers.get(index)
        );

        if ((index + 1) % batchSize == 0) {

            entityManager.flush();
            entityManager.clear();
        }
    }

    entityManager.flush();
    entityManager.clear();
}

Common Mistake

Believing JDBC batching alone prevents persistence-context memory growth.

Senior Follow-up

JDBC batching reduces database round trips, while clear() controls persistence-context memory. Both may be required.


Q12. Give a production example of First-Level Cache.

Scenario

An order service validates an order, customer, and payment profile within one transaction.

@Transactional
public void approveOrder(Long orderId) {

    Order order =
        entityManager.find(Order.class, orderId);

    Customer customer =
        entityManager.find(
            Customer.class,
            order.getCustomer().getId()
        );

    validateCustomer(customer);

    Customer sameCustomer =
        entityManager.find(
            Customer.class,
            customer.getId()
        );

    approve(order, sameCustomer);
}

If customer and sameCustomer use the same entity type and ID within one persistence context:

customer == sameCustomer

is normally:

true

Benefits

  • Avoids duplicate entity retrieval
  • Maintains consistent in-memory state
  • Supports dirty checking
  • Simplifies transactional logic

SQL Behavior

Load Order
    │
    ▼
Load Customer
    │
    ▼
Request Same Customer Again
    │
    ▼
First-Level Cache Hit
    │
    ▼
No Additional Customer SELECT

Common Mistake

Relying on First-Level Cache as a general-purpose application cache.

Senior Follow-up

It improves consistency within one unit of work, but it does not replace CDN, Redis, application caches, or Hibernate Second-Level Cache.


Q13. What are common First-Level Cache interview mistakes?

Answer

Common mistakes include:

  • Saying First-Level Cache is optional.
  • Assuming it is shared across sessions.
  • Confusing it with Second-Level Cache.
  • Treating it as a global application cache.
  • Assuming repeated queries always avoid SQL.
  • Forgetting that JPQL collection queries may still execute.
  • Ignoring persistence-context memory growth.
  • Calling clear() before flush().
  • Expecting detached entities to remain cached.
  • Assuming cache contents automatically refresh from external database changes.
  • Sharing one session across multiple threads.
  • Keeping one session open for too long.
  • Assuming flush() clears the cache.
  • Believing JDBC batching automatically clears managed entities.
  • Using cached managed entities without considering staleness.

Important Query Nuance

This may execute twice:

List<Customer> first = entityManager
    .createQuery(
        "select c from Customer c",
        Customer.class
    )
    .getResultList();

List<Customer> second = entityManager
    .createQuery(
        "select c from Customer c",
        Customer.class
    )
    .getResultList();

The query itself can run twice because First-Level Cache is not a general query-result cache.

However, Hibernate may reuse already managed entity instances while processing the second result.

Interview Tip

Distinguish entity caching from query-result caching.


Q14. What are the performance implications of First-Level Cache?

Answer

First-Level Cache has both benefits and costs.

Benefits

  • Avoids repeated entity loading by identifier
  • Maintains entity identity
  • Supports write-behind
  • Enables dirty checking
  • Reduces duplicate entity instances
  • Keeps transaction behavior consistent

Costs

  • Retains entity references
  • Increases heap usage
  • Increases dirty-checking work
  • Can hold stale data
  • Increases flush cost
  • Can become expensive in batch workloads

Performance Balance

Small Transaction
      │
      ▼
Few Managed Entities
      │
      ▼
First-Level Cache Helpful

Large Transaction
      │
      ▼
Thousands or Millions of Entities
      │
      ▼
Memory and Dirty-Checking Cost

Production Optimization Options

  • Keep transactions appropriately sized.
  • Use DTO projections for read-only screens.
  • Use pagination or streaming.
  • Flush and clear in batches.
  • Mark queries read-only.
  • Avoid loading unnecessary relationships.
  • Use StatelessSession for specialized workloads.
  • Avoid Open Session in View for uncontrolled entity graphs.

Common Mistake

Optimizing by clearing the persistence context too frequently without considering required entity relationships or pending state.

Senior Follow-up

Batch size should be tested based on heap size, SQL batching, database latency, transaction duration, and failure-recovery requirements.


Q15. What are senior-level First-Level Cache best practices?

Answer

Senior developers should treat the persistence context as a controlled unit-of-work boundary.

Best Practices

  • Keep one persistence context per business transaction.
  • Keep transactions reasonably short.
  • Avoid loading large object graphs unnecessarily.
  • Use DTO projections for read-only use cases.
  • Use pagination for large result sets.
  • Flush and clear during bulk writes.
  • Avoid sharing sessions across threads.
  • Use refresh() only when database reloading is genuinely required.
  • Detach entities only for a clear reason.
  • Monitor SQL rather than assuming cache hits.
  • Separate First-Level Cache from query caching concepts.
  • Do not expose managed entities directly through APIs.
  • Use read-only query hints for read-heavy operations.
  • Consider optimistic locking for stale-update protection.
  • Test memory behavior under production-scale data volumes.

Production Checklist

Begin Transaction
      │
      ▼
Load Only Required Entities
      │
      ▼
Perform Business Changes
      │
      ▼
Flush Changes
      │
      ▼
Commit Transaction
      │
      ▼
Close Persistence Context

Batch Checklist

Persist Batch
     │
     ▼
flush()
     │
     ▼
clear()
     │
     ▼
Continue Next Batch

Senior Follow-up

The First-Level Cache should be understood primarily as an identity map and unit-of-work mechanism, not as a substitute for a distributed caching strategy.


First-Level Cache Architecture

flowchart TD

APP["Spring Boot Application"]

APP --> SESSION["Hibernate Session"]

SESSION --> PC["Persistence Context"]

PC --> MANAGED["Managed Entities"]

PC --> SNAPSHOT["Original Entity Snapshots"]

PC --> ACTIONS["Pending INSERT / UPDATE / DELETE"]

MANAGED --> DIRTY["Dirty Checking"]

SNAPSHOT --> DIRTY

DIRTY --> FLUSH["Flush Engine"]

ACTIONS --> FLUSH

FLUSH --> SQL["Generate SQL"]

SQL --> JDBC["JDBC"]

JDBC --> DB["Database"]

First-Level Cache Lookup Flow

flowchart TD

A["find(Customer,101)"]

A --> B["Persistence Context"]

B --> C{"Cache Hit?"}

C -->|Yes| D["Return Same Managed Entity"]

C -->|No| E["Execute SELECT"]

E --> F["Load Entity"]

F --> G["Store in First-Level Cache"]

G --> H["Return Managed Entity"]

D --> I["No SQL Executed"]

H --> J["Future Lookups Use Cache"]

Entity Identity Guarantee

Persistence Context
        │
        ▼
Customer#101
        │
        ▼
One Managed Java Object

Within one persistence context:

firstCustomer == secondCustomer

is normally:

true

First-Level vs Second-Level Cache

Feature First-Level Cache Second-Level Cache
Scope Session / persistence context SessionFactory
Enabled by default Yes No
Mandatory Yes No
Shared across sessions No Yes
Stores entities Yes Yes
Query results No Separate query cache
Configuration required No Yes
Primary purpose Identity and unit of work Reduce database access across sessions

First-Level Cache vs Query Cache

First-Level Cache Query Cache
Stores managed entities Stores query result identifiers/scalars
Session scoped Usually SessionFactory scoped
Always enabled Optional
Used by entity lookup Used for repeated cacheable queries
Maintains identity Reuses query result metadata
No special configuration Requires explicit configuration

find() Example

@Transactional
public void demonstrateCache(Long customerId) {

    Customer first =
        entityManager.find(
            Customer.class,
            customerId
        );

    Customer second =
        entityManager.find(
            Customer.class,
            customerId
        );

    if (first != second) {
        throw new IllegalStateException(
            "Expected the same managed instance"
        );
    }
}

Expected behavior:

One SELECT
Two Java References
One Managed Entity Instance

detach() Example

@Transactional
public void detachCustomer(Long customerId) {

    Customer customer =
        entityManager.find(
            Customer.class,
            customerId
        );

    entityManager.detach(customer);

    customer.setEmail(
        "[email protected]"
    );
}

After detaching, changing the entity does not automatically trigger an update.


clear() Example

@Transactional
public void clearPersistenceContext(
    Long customerId
) {

    Customer first =
        entityManager.find(
            Customer.class,
            customerId
        );

    entityManager.clear();

    Customer second =
        entityManager.find(
            Customer.class,
            customerId
        );

    System.out.println(first == second);
}

Output:

false

Hibernate may execute another SELECT after clear().


refresh() Example

@Transactional
public Customer reloadCustomer(
    Long customerId
) {

    Customer customer =
        entityManager.find(
            Customer.class,
            customerId
        );

    entityManager.refresh(customer);

    return customer;
}

refresh() reloads the managed entity from the database and overwrites its current state.


Batch Insert Pattern

@Transactional
public void insertCustomers(
    List<Customer> customers
) {

    int batchSize = 1000;

    for (int index = 0;
         index < customers.size();
         index++) {

        entityManager.persist(
            customers.get(index)
        );

        if ((index + 1) % batchSize == 0) {

            entityManager.flush();
            entityManager.clear();
        }
    }

    entityManager.flush();
    entityManager.clear();
}

First-Level Cache Memory Growth

Load 1 Entity
     │
     ▼
Persistence Context Size: 1

Load 10,000 Entities
     │
     ▼
Persistence Context Size: 10,000

Load 1,000,000 Entities
     │
     ▼
High Heap Usage
High Dirty-Checking Cost
Long Flush Duration

Production Transaction Pattern

Controller
    │
    ▼
Transactional Service
    │
    ▼
Repository / EntityManager
    │
    ▼
Persistence Context
    │
    ▼
First-Level Cache
    │
    ▼
Database

Common First-Level Cache Scenarios

Scenario Expected Behavior
Same find() twice in one context Usually one query
Same find() in two sessions Query per session
Call detach() Entity removed from cache
Call clear() All entities removed
Close EntityManager Cache discarded
Modify managed entity Dirty checking applies
Modify detached entity No automatic update
Execute same JPQL query twice Query may execute twice
Batch insert without clear Cache grows continuously
refresh() managed entity Reload from database

Interview Quick Revision

Concept Purpose
First-Level Cache Session-level managed entity cache
Persistence Context Entity lifecycle and identity management
Identity Map One entity instance per type and ID
find() Loads or returns managed entity
detach() Removes one entity from context
evict() Hibernate-native detach operation
clear() Removes all managed entities
refresh() Reloads entity from database
Dirty Checking Detects managed-entity changes
Flush Synchronizes persistence context
Session Scope Cache lifetime boundary
Entity Snapshot Supports change detection
DTO Projection Avoids managed entity creation
StatelessSession No normal persistence context
Batch Processing Requires controlled flush and clear

Key Takeaways

  • Hibernate First-Level Cache is a mandatory cache associated with one Session or JPA persistence context.
  • It is enabled automatically and cannot be disabled in a normal stateful Hibernate session.
  • The cache stores managed entity instances by entity type and identifier.
  • Fetching the same entity twice within one persistence context normally returns the same Java object.
  • First-Level Cache is not shared across sessions, transactions with separate contexts, application instances, or users.
  • The persistence context provides more than caching; it also manages lifecycle, dirty checking, cascading, and synchronization.
  • detach() or evict() removes one entity, while clear() removes every managed entity.
  • When a typical transaction-scoped persistence context closes, the cache is discarded and entities become detached.
  • Dirty checking depends on managed entities and their tracked state inside the persistence context.
  • Large persistence contexts increase heap usage, dirty-checking work, and flush duration.
  • JDBC batching does not automatically solve persistence-context memory growth.
  • Bulk processing should use controlled flush() and clear() operations.
  • First-Level Cache does not cache arbitrary query results; repeated JPQL queries may still execute.
  • DTO projections and read-only queries are useful for read-heavy operations that do not require entity management.
  • First-Level Cache should be understood as an identity map and unit-of-work mechanism rather than a global application cache.