JPA, Hibernate, and Data· 45 min

Hibernate Fetching, Locking, and Transactions

Solve lazy loading, N+1 queries, locking, cascading, and transaction boundary problems.

Java interview lesson
Question 23 · Not reviewed

Data · Hibernate runtime

Can you explain this clearly in an interview?

Use the strong answer as your reference, explain it aloud in your own words, then choose how soon you want to review it again.

Interview prompt

Hibernate Fetching, Locking, and Transactions

Explain it aloud in your own words

Strong answer

Hibernate executes SQL lazily based on how the persistence context is navigated, so performance problems usually come from fetch plans rather than from slow Java code. Solve N+1 queries with use-case-specific JOIN FETCH queries, entity graphs, or batch fetching; protect concurrent updates with optimistic @Version checks by default and pessimistic locks only for short, high-contention sections; and keep the transaction boundary around one business operation so dirty checking flushes predictably.

Key points

  • N+1 happens when one query loads parents and each lazy collection or reference triggers another query.
  • Open Session in View hides lazy-loading problems by running queries during response rendering; disable it and fetch deliberately.
  • @Version turns a lost update into an OptimisticLockException that the caller can retry or report.
  • Fetching a collection with JOIN FETCH plus pagination makes Hibernate paginate in memory; page ids first, then fetch.

Interviewer looks for

Show how you detect N+1 (SQL logs, statistics, query counts in tests), choose between fetch join, entity graph, and batch size, and explain what happens when two transactions update the same row.

Java example

1interface OrderRepository extends JpaRepository<Order, Long> {
2
3  @Query("select distinct o from Order o join fetch o.lines where o.customer.id = :customerId")
4  List<Order> findWithLines(@Param("customerId") long customerId);
5
6  @EntityGraph(attributePaths = {"customer"})
7  Page<Order> findByStatus(OrderStatus status, Pageable pageable);
8}
9
10@Entity
11class Inventory {
12  @Id private Long sku;
13  private int available;
14  @Version private long version; // optimistic locking
15}

Topic interview questions

Revise this topic like an interviewer

These questions are tied to this lesson. Read each question aloud, then compare your explanation with the strong answer.

5 questions
Q1Basic

What is the N+1 query problem and how do you fix it in Hibernate?

Strong answer

One query loads N parent rows and then accessing a lazy association on each parent issues one more query per row. Fix it per use case with a JOIN FETCH query, an @EntityGraph, or @BatchSize/default batch fetching, and verify the fix by asserting the number of executed statements.

Q2Intermediate

Why does LazyInitializationException happen?

Strong answer

A lazy proxy or collection is accessed after the persistence context that loaded it has closed, so Hibernate cannot run the query. The right fix is to fetch the data inside the transaction or map to a DTO there, not to switch everything to EAGER or rely on Open Session in View.

Q3Intermediate

How does optimistic locking with @Version work?

Strong answer

Hibernate includes the version column in the UPDATE's WHERE clause and increments it. If another transaction changed the row first, zero rows match and Hibernate throws an optimistic lock exception, so the application can retry with fresh state or return a conflict to the client.

Q4Advanced

When would you use a pessimistic lock instead?

Strong answer

When contention is high and retries are expensive or unsafe, such as reserving a scarce resource. PESSIMISTIC_WRITE issues SELECT ... FOR UPDATE, so keep the transaction short, set a lock timeout, and acquire rows in a consistent order to avoid deadlocks.

Q5Advanced

Why is combining JOIN FETCH on a collection with pagination dangerous?

Strong answer

The join multiplies rows per parent, so the database cannot apply LIMIT to parents correctly. Hibernate warns and applies pagination in memory after loading everything. Instead, page the parent ids first and then fetch the collections for that id list.

How well do you know this?

Your review choice is saved locally and synced to your learner profile when signed in.