Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: Fresher to 2 Years

Java Basics, JVM & Memory

  • JDK, JRE, JVM & the main Method — Interview Questions
  • JVM Memory & Garbage Collection — Interview Questions
  • Data Types, Wrapper Classes & Equality — Interview Questions

Object-Oriented Programming

  • Classes, Objects, Packages & Access Modifiers — Interview Questions
  • Inheritance, Composition, this & super — Interview Questions
  • Polymorphism, Overloading & Overriding — Interview Questions
  • Abstraction, Interfaces & Encapsulation — Interview Questions
  • Constructors, Singleton, Anonymous Classes & Immutability — Interview Questions
  • Design Patterns & SOLID Basics — Interview Questions

Strings, Keywords, Exceptions & Serialization

  • Strings, String Pool, StringBuilder & StringBuffer — Interview Questions
  • static & final Keywords — Interview Questions
  • Exceptions, Generics, Enums & Reflection — Interview Questions
  • Serialization & transient — Interview Questions

Collections Framework

  • Collections Framework Basics — Interview Questions
  • HashMap, HashSet & TreeMap Internals — Interview Questions

Multithreading Basics

  • Threads, Synchronization & volatile Basics — Interview Questions

Java 8+ & Stream API

  • Java 8 to Java 21 Features — Interview Questions
  • Stream API Coding Questions (Part 1) — Interview Questions
  • Stream API Coding Questions (Part 2) — Interview Questions

Coding Round Programs

  • Classic Number & String Programs — Interview Questions
  • String & Collection Programs — Interview Questions
  • Array & String Problem Solving — Interview Questions

Spring Framework Core

  • Spring IoC, Dependency Injection & Beans — Interview Questions
  • Spring Injection Types, Scopes, Profiles & WebFlux — Interview Questions

Spring Boot Essentials

  • Spring Boot Fundamentals — Interview Questions
  • Spring Boot Runners, Servers & Configuration — Interview Questions
  • Spring Boot Controllers, Profiles, Actuator & DevTools — Interview Questions
  • Spring Boot Testing, Exceptions & Auto-Configuration — Interview Questions
  • REST APIs, Swagger, Embedded Servers & Key Annotations — Interview Questions

Spring MVC

  • Spring MVC Architecture & DispatcherServlet — Interview Questions
  • Spring MVC Request Mapping & Controllers — Interview Questions
  • Spring MVC Forms, Views & Interceptors — Interview Questions
  • Spring MVC Exceptions, Security & Dependency Injection — Interview Questions
  • Spring MVC Data Binding, Static Resources & Path Variables — Interview Questions
  • Spring MVC i18n, Testing, File Uploads & Scaling — Interview Questions

Hibernate & Spring Data JPA

  • Hibernate & JPA Core Concepts — Interview Questions
  • Hibernate Performance, Mapping & Scenarios — Interview Questions

SQL

  • SQL Basics, Keys, Normalization & Transactions — Interview Questions
  • SQL Joins, Triggers, Procedures, Functions & Indexes — Interview Questions
  • SQL "Difference Between" Questions — Interview Questions
  • SQL Query Writing (Part 1) — Interview Questions
  • SQL Query Writing (Part 2) — Interview Questions

Microservices Basics

  • Microservices, API Gateway & Communication — Interview Questions
  • Service Discovery, Data Consistency & Deployment — Interview Questions
  • Microservices Monitoring, Security & Resilience — Interview Questions

Maven & Git

  • Maven — Interview Questions
  • Git — Interview Questions
Chaturmind
← Java Interview Prep: Fresher to 2 Years

Java Basics, JVM & Memory

  • JDK, JRE, JVM & the main Method — Interview Questions
  • JVM Memory & Garbage Collection — Interview Questions
  • Data Types, Wrapper Classes & Equality — Interview Questions

Object-Oriented Programming

  • Classes, Objects, Packages & Access Modifiers — Interview Questions
  • Inheritance, Composition, this & super — Interview Questions
  • Polymorphism, Overloading & Overriding — Interview Questions
  • Abstraction, Interfaces & Encapsulation — Interview Questions
  • Constructors, Singleton, Anonymous Classes & Immutability — Interview Questions
  • Design Patterns & SOLID Basics — Interview Questions

Strings, Keywords, Exceptions & Serialization

  • Strings, String Pool, StringBuilder & StringBuffer — Interview Questions
  • static & final Keywords — Interview Questions
  • Exceptions, Generics, Enums & Reflection — Interview Questions
  • Serialization & transient — Interview Questions

Collections Framework

  • Collections Framework Basics — Interview Questions
  • HashMap, HashSet & TreeMap Internals — Interview Questions

Multithreading Basics

  • Threads, Synchronization & volatile Basics — Interview Questions

Java 8+ & Stream API

  • Java 8 to Java 21 Features — Interview Questions
  • Stream API Coding Questions (Part 1) — Interview Questions
  • Stream API Coding Questions (Part 2) — Interview Questions

Coding Round Programs

  • Classic Number & String Programs — Interview Questions
  • String & Collection Programs — Interview Questions
  • Array & String Problem Solving — Interview Questions

Spring Framework Core

  • Spring IoC, Dependency Injection & Beans — Interview Questions
  • Spring Injection Types, Scopes, Profiles & WebFlux — Interview Questions

Spring Boot Essentials

  • Spring Boot Fundamentals — Interview Questions
  • Spring Boot Runners, Servers & Configuration — Interview Questions
  • Spring Boot Controllers, Profiles, Actuator & DevTools — Interview Questions
  • Spring Boot Testing, Exceptions & Auto-Configuration — Interview Questions
  • REST APIs, Swagger, Embedded Servers & Key Annotations — Interview Questions

Spring MVC

  • Spring MVC Architecture & DispatcherServlet — Interview Questions
  • Spring MVC Request Mapping & Controllers — Interview Questions
  • Spring MVC Forms, Views & Interceptors — Interview Questions
  • Spring MVC Exceptions, Security & Dependency Injection — Interview Questions
  • Spring MVC Data Binding, Static Resources & Path Variables — Interview Questions
  • Spring MVC i18n, Testing, File Uploads & Scaling — Interview Questions

Hibernate & Spring Data JPA

  • Hibernate & JPA Core Concepts — Interview Questions
  • Hibernate Performance, Mapping & Scenarios — Interview Questions

SQL

  • SQL Basics, Keys, Normalization & Transactions — Interview Questions
  • SQL Joins, Triggers, Procedures, Functions & Indexes — Interview Questions
  • SQL "Difference Between" Questions — Interview Questions
  • SQL Query Writing (Part 1) — Interview Questions
  • SQL Query Writing (Part 2) — Interview Questions

Microservices Basics

  • Microservices, API Gateway & Communication — Interview Questions
  • Service Discovery, Data Consistency & Deployment — Interview Questions
  • Microservices Monitoring, Security & Resilience — Interview Questions

Maven & Git

  • Maven — Interview Questions
  • Git — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: Fresher to 2 YearsHibernate & Spring Data JPA
✓ FreeBeginner· 9 min read

Hibernate Performance, Mapping & Scenarios — Interview Questions

The N+1 problem and its fixes, @Entity, cascading, composite keys, SQL injection safety, lazy loading, concurrency and optimistic locking, plus five real scenarios — slow relationship fetching, session handling in web apps, rollback, auditing with Envers and mapping legacy schemas.

Published September 25, 2026


How to use this lesson

The N+1 problem, lazy loading and optimistic locking are the Hibernate topics that come up in real production incidents, which is why interviewers love them. The scenario questions at the end test judgement. Answer with the specific feature you'd use, and why.

Q1. What is the N+1 SELECT problem, and how do you prevent it?

Short answer: You run 1 query to load N parent rows. Then, as your code touches a lazy association on each parent, Hibernate runs N more queries, one per parent. It's invisible in the code, and it gets devastating as N grows.

List<Order> orders = orderRepository.findAll();              // 1 query
for (Order o : orders) {
    System.out.println(o.getCustomer().getName());           // +1 query per order → N+1
}

Fixes:

  • A fetch join loads the association in the same query: select o from Order o join fetch o.customer.
  • An entity graph: @EntityGraph(attributePaths = "customer") on a Spring Data method.
  • Batch fetching: @BatchSize(size = 50), or hibernate.default_batch_fetch_size. This loads the associations in groups with IN (…).
  • DTO projections: select exactly the columns you need (select new com.shop.OrderSummary(o.id, c.name) …).

Key points to cover:

  • Detect it by logging SQL (org.hibernate.SQL=DEBUG), enabling Hibernate statistics, or using tools like the Hypersistence Optimizer. Watch the query counts in tests.
  • Fetch-joining collections together with pagination makes Hibernate paginate in memory (warning HHH90003004). Page the IDs first, then fetch the entities.

Learn it in depth → N+1 Query Problem

Q2. What does @Entity do?

Short answer: It marks a class as a JPA entity, meaning its instances map to rows of a table and can be persisted. An entity needs:

  • an @Id;
  • a no-argument constructor (it can be protected);
  • a non-final class, so that proxies can extend it.
@Entity
@Table(name = "orders")
public class Order {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
    @Column(nullable = false) private String status;
    @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "customer_id") private Customer customer;
    @Version private int version;                   // optimistic locking
    protected Order() { }                           // for JPA
}

Q3. What is cascading?

Short answer: Cascading propagates entity operations from a parent to its associated children. CascadeType.PERSIST, MERGE, REMOVE, REFRESH, DETACH, or ALL. For example, saving an Order also saves its new OrderLines.

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderLine> lines = new ArrayList<>();

Key points to cover:

  • Cascade only from a true owner to its dependent children (composition). Never cascade REMOVE across shared associations such as @ManyToOne, or deleting one order could delete a customer.
  • orphanRemoval = true deletes a child that's removed from the collection.

Q4. What is a composite key, and how do you map it?

Short answer: A primary key made of several columns, for example (order_id, line_no). Map it with an @Embeddable key class used as an @EmbeddedId (preferred), or with @IdClass. The key class must implement equals/hashCode, and be Serializable.

@Embeddable
public record OrderLineId(Long orderId, Integer lineNo) implements Serializable { }

@Entity
public class OrderLine {
    @EmbeddedId private OrderLineId id;
    @MapsId("orderId") @ManyToOne(fetch = FetchType.LAZY) private Order order;
    private int quantity;
}

Key points to cover:

  • Records as embeddables are supported from Hibernate 6.2.
  • Many teams prefer a surrogate single-column ID plus a unique constraint on the natural columns. It keeps foreign keys and URLs simple.

Q5. How does Hibernate protect against SQL injection?

Short answer: When you use parameter binding, values are sent as PreparedStatement parameters, never concatenated into the SQL text. This applies to JPQL/HQL named or positional parameters, the Criteria API, and Spring Data derived queries. It doesn't protect you if you build query strings by concatenating user input, whether in HQL or native SQL.

// ❌ vulnerable: user input becomes part of the query text
em.createQuery("from User u where u.email = '" + email + "'");
// ✅ safe: bound parameter
em.createQuery("from User u where u.email = :email", User.class).setParameter("email", email);

Key points to cover:

  • Dynamic sort columns or table names can't be bound as parameters. Check them against an allow-list.

Q6. What is lazy loading?

Short answer: Deferring the loading of an association until it's first accessed. Hibernate injects a proxy, or an uninitialised collection wrapper, and runs the query on first use. It's the default for @OneToMany and @ManyToMany, and it's recommended for @ManyToOne too (which defaults to EAGER).

Common trap: a LazyInitializationException ("could not initialize proxy – no Session") when a lazy association is touched after the transaction or persistence context has closed. That happens, for example, in a controller, or while Jackson serialises an entity. Fix it by fetching what you need inside the service transaction (fetch join or entity graph), and returning DTOs. Don't make everything EAGER.

Q7. How do you handle concurrency in Hibernate?

Short answer: With locking:

  • Optimistic locking (@Version): no database locks. It detects conflicting updates at commit time.
  • Pessimistic locking (@Lock(LockModeType.PESSIMISTIC_WRITE) → SELECT … FOR UPDATE): locks the rows while you work, for heavily contended data such as stock counters or seat bookings.

Combine them with the right transaction isolation level.

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select s from Stock s where s.sku = :sku")
Stock lockBySku(@Param("sku") String sku);

Learn it in depth → Transactions & Isolation Levels

Q8. What is optimistic locking?

Short answer: Each row carries a version column (@Version). An update includes the version it read in its condition: UPDATE … SET …, version = 6 WHERE id = ? AND version = 5. If another transaction changed the row in the meantime, zero rows are updated, and Hibernate throws an OptimisticLockException (Spring translates it to ObjectOptimisticLockingFailureException).

Key points to cover:

  • It's ideal when conflicts are rare. There's no locking overhead, and it prevents lost updates (two users editing the same product).
  • On a conflict, retry the operation (with a fresh read), or show the user a "record changed, please reload" message.

Q9. Scenario: fetching entities with many relationships is slow. What would you do?

Short answer:

  1. Measure first: enable SQL logging or statistics, and count the queries.
  2. Make associations LAZY by default, so unused data isn't loaded.
  3. Where a use case needs the related data, load it in one go, using fetch joins, @EntityGraph, or batch fetching, which fixes N+1.
  4. Use DTO projections for read-only screens.
  5. Paginate.
  6. Add the right indexes on foreign keys and filter columns.
  7. Consider the second-level cache for read-mostly reference data.

Common trap: answering only "use lazy loading". Lazy loading alone is often what causes the N+1 storm. The real fix is to fetch each use case's data deliberately.

Q10. Scenario: how do you manage Hibernate sessions in a web application so they're always closed?

Short answer: Let the framework own them. In Spring, the EntityManager is bound to the transaction (@Transactional on the service layer), and it's opened and closed automatically, even when exceptions occur. In plain Hibernate, use the session-per-request pattern: open the session in a servlet filter, and close it in finally, or use getCurrentSession() with thread-bound context management.

Key points to cover:

  • Spring Boot enables Open Session in View by default (spring.jpa.open-in-view=true, with a startup warning). It keeps the session open through view rendering, which hides lazy-loading problems, and holds database connections longer. Most teams set it to false, and fetch what they need in the service layer.

Q11. Scenario: an error happens after several database operations in a transaction. How is integrity preserved?

Short answer: Everything happened inside one transaction, so the failure triggers a rollback. The database discards every change made in that transaction, and no partial update remains. In Spring, @Transactional rolls back automatically on unchecked exceptions and Errors.

Common trap: a checked exception doesn't roll back by default in Spring. Use @Transactional(rollbackFor = Exception.class) if checked exceptions should roll back. Also, catching the exception inside the method and swallowing it means the transaction commits.

Learn it in depth → @Transactional Deep Dive

Q12. Scenario: you need to audit changes to entity data. What would you use?

Short answer: Hibernate Envers. Annotate entities with @Audited. For every change, Envers writes a revision into _AUD tables, recording the revision number, the type of change (add, modify or delete) and the entity's state. AuditReader then queries the history ("what did this order look like last Tuesday?").

Key points to cover:

  • A custom @RevisionEntity can record who made the change (the current user) and why.
  • For simple "created by / modified at" columns, Spring Data JPA auditing is lighter: @CreatedDate, @LastModifiedBy, plus @EnableJpaAuditing.

Q13. Scenario: map a legacy database whose table and column names don't follow your conventions.

Short answer: Map the names explicitly, without changing the schema: @Table(name = "TBL_CUST_MSTR") and @Column(name = "CUST_NM"). Use @JoinColumn for foreign keys, and @Convert / AttributeConverter for odd encodings (for example 'Y'/'N' flags to boolean). For systematic rules, implement a PhysicalNamingStrategy.

@Entity
@Table(name = "TBL_CUST_MSTR")
public class Customer {
    @Id @Column(name = "CUST_ID") private Long id;
    @Column(name = "CUST_NM") private String name;
    @Convert(converter = YesNoConverter.class) @Column(name = "ACTV_FLG") private boolean active;   // 'Y'/'N'
}

Key points to cover:

  • Set spring.jpa.hibernate.ddl-auto=validate (or none), so Hibernate never tries to alter the legacy schema.

Follow-up questions this topic invites — and their answers

Q: What does spring.jpa.hibernate.ddl-auto do, and what should production use? A: It controls schema generation: create, create-drop, update, validate or none. Production should use validate or none, with schema changes managed by migration tools such as Flyway or Liquibase.

Q: How do you see the SQL that Hibernate generates? A: Set logging.level.org.hibernate.SQL=DEBUG, plus org.hibernate.orm.jdbc.bind=TRACE for the parameter values. spring.jpa.show-sql=true also works, but it prints to stdout, not through your logger.

Q: What is @Transactional(readOnly = true) good for? A: It tells Hibernate to skip dirty checking and flushing, and some drivers or databases route such transactions to replicas. Use it on query methods.

Q: Why implement equals/hashCode carefully in entities? A: IDs are often generated only on persist, so an ID-based hashCode changes after saving, which breaks HashSet membership. Use a business key, or a constant hashCode with ID-based equals (null-safe) for entities.

Previous

Hibernate & JPA Core Concepts — Interview Questions

Next

SQL Basics, Keys, Normalization & Transactions — Interview Questions

AI Tutor

Lesson: Hibernate Performance, Mapping & Scenarios — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.