$ Spring Data JPA & Hibernate — Complete Interview Revision
// 5-7 Yrs Experience — ORM, Entity Lifecycle, Relationships, Querying, Transactions, Locking & Performance
1. ORM, JPA, Hibernate & Spring Data JPA
Without ORM
Java Object
Write SQL → Execute JDBC
Convert ResultSet → Create Object
Return Object
With ORM
Java Object
ORM Framework → SQL Generated Automatically
Database
Java Object
ORM (Object Relational Mapping) → maps Java Objects to Database Tables automatically. Benefits: Less Boilerplate Code, Database Independent, Automatic CRUD, Object-Oriented Programming, Better Productivity, Easier Maintenance.
JPA, Hibernate & Spring Data JPA Stack
Definitions
JPA (Java Persistence API) → a Specification for ORM in Java. Defines interfaces, rules, annotations — but provides no implementation. Hibernate → the most popular implementation of the JPA specification. Responsibilities: ORM, SQL Generation, Caching, Dirty Checking, Lazy Loading, Transactions, Performance Optimization. Spring Data JPA → builds on top of JPA to reduce boilerplate. Provides Repository interfaces, automatic queries, pagination, sorting, specifications.
Spring Data JPA Stack
Application
Spring Data JPA
JPA (Specification)
Hibernate (Implementation)
JDBC
Database
JPA vs Hibernate vs Spring Data JPA
JPA
Specification, Standard API, Interfaces, Portable
Hibernate
Implementation, Framework, Concrete Classes, Feature Rich — uses EntityManager, manual repository code
Spring Data JPA
Repository Abstraction, Less Code, Automatic CRUD
2. Entity & Repository Basics
Entity — Common Annotations
An Entity represents a database table; each object represents one row. @Entity marks entity @Table database table @Id primary key @GeneratedValue generate primary key @Column map column @Transient ignore field @Enumerated store enum @Lob large object
Primary Key Generation
AUTO → Provider Chooses IDENTITY → Database Auto Increment SEQUENCE → Database Sequence TABLE → Sequence Table (rarely used, slowest)
Repository Hierarchy
Repository └── CrudRepository → Basic CRUD (save, findById, findAll, delete) └── PagingAndSortingRepository → Extends CrudRepository, adds Pagination + Sorting └── JpaRepository → Extends PagingAndSortingRepository, adds Batch Operations, Flush, JPA-specific methods
Repository Comparison
RepositoryProvides
CrudRepositoryCRUD Only
PagingAndSortingRepositoryCRUD + Pagination + Sorting
JpaRepository ⭐Everything + Flush + Batch + JPA Features (recommended default)
3. EntityManager & Persistence Context
EntityManager
Core interface of JPA — responsible for managing entities, the persistence context, and database operations. Common methods: persist(), merge(), find(), remove(), flush(), refresh(), detach()
EntityManager Flow
Application → Repository
EntityManager → Hibernate
JDBC → Database
Persistence Context & Persistence Unit
Persistence Context
First-Level Cache, managed by EntityManager. Stores managed entities during a transaction.
Persistence Unit
Configuration that defines entities, database, persistence provider, transaction settings — usually configured automatically in Spring Boot.
Why Persistence Context?
Avoid Duplicate Queries
Track Entity Changes
Dirty Checking
Improve Performance
Maintain Entity Identity
Spring Data JPA Request Flow
Client → Controller → Service
JpaRepository → EntityManager
Hibernate → JDBC → Database
Entity → JSON Response
4. Entity Lifecycle
Entity Lifecycle Flow
new Entity → Transient
↓ persist()
Persistent
↓ detach()
Detached
↓ merge()
Persistent
↓ remove()
Removed
↓ Commit
Deleted
Transient
New object created using new — not managed by EntityManager, not stored in database (e.g. User user = new User();)
Persistent
Managed by the Persistence Context — changes automatically tracked and synchronized with the database
Detached
Entity exists but is no longer managed. Caused by: Transaction Ends, detach(), EntityManager Closed, clear()
Removed
Entity marked for deletion — will be deleted during flush or commit
EntityManager Operations
MethodPurpose
persist()Insert a new (Transient only) entity → becomes Persistent; INSERT generated during flush/commit
merge()Copy a Detached entity's state into a Persistent entity — INSERT or UPDATE, returns the managed entity
find()Retrieve an entity immediately by primary key — checks Persistence Context first, else queries DB
getReference()Return a lazy proxy without immediately fetching data — DB query occurs only when data is accessed
remove()Mark entity for deletion — moves to Removed state; DELETE executed at flush/commit
refresh()Reload entity from database — discard local changes, get latest DB values
detach()Remove entity from Persistence Context — further changes are not tracked
flush()Synchronize Persistence Context with the database
persist() vs merge() & find() vs getReference()
persist()
New Entity, INSERT, fails if the entity already exists
merge()
Existing / Detached Entity, INSERT or UPDATE, returns a managed entity
find()
Immediately loads the entity
getReference()
Returns a proxy, loads on demand
5. Dirty Checking, Flush vs Commit & save() vs saveAndFlush()
Dirty Checking Flow
find() → Persistent Entity
Modify Field (no explicit save())
Commit → Hibernate Detects Change
UPDATE Executed Automatically
Dirty Checking works when: the entity is Persistent, inside an active transaction, and managed. It does not work for a Detached entity.
Flush vs Commit
Flush
Synchronizes Persistence Context with DB without ending the transaction — executes SQL, transaction still active, can still rollback
Commit
Flush → Ends transaction → Changes become permanent → Releases resources
save() vs saveAndFlush()
save()
Saves entity, flush happens later at commit (default) — better performance
saveAndFlush()
Save + immediate flush to DB — more database calls. Use when you need a DB-generated value immediately, an immediate query, or stored procedures
6. Entity Relationships
@OneToOne → One record related to exactly one record — User ↔ Profile, Employee ↔ Passport @OneToMany → One parent has multiple children — Department → Employees, Order → Order Items @ManyToOne → Many records belong to one parent — Employees → Department, Orders → Customer @ManyToMany → Many records related to many records, using a join table — Students ↔ Courses, Users ↔ Roles
Owning Side, Inverse Side, mappedBy, @JoinColumn & @JoinTable
Owning Side vs Inverse Side
Owning Side → the entity that owns the foreign key, controls the relationship & updates. Usually the @ManyToOne / @JoinColumn side. Inverse Side → the entity using mappedBy, does not own the relationship — avoids duplicate relationship mapping. Benefits: single foreign key, no duplicate mapping, better consistency.
@JoinColumn vs @JoinTable
@JoinColumn → defines the foreign key column in the database (e.g. employee.department_id) @JoinTable → defines the join table for @ManyToMany relationships
7. Cascade Types & Orphan Removal
CascadeType.PERSISTParent saved → Child saved
CascadeType.MERGEParent updated → Child updated
CascadeType.REMOVEParent deleted → Child deleted
CascadeType.REFRESHParent reloaded → Child reloaded
CascadeType.DETACHParent detached → Child detached
CascadeType.ALLIncludes PERSIST, MERGE, REMOVE, REFRESH, DETACH
Orphan Removal & Cascade vs Orphan Removal
Cascade REMOVE
Deletes child when the parent is deleted
Orphan Removal
Deletes child automatically when removed from the parent's collection — e.g. Order → remove Item → Item deleted automatically
8. Fetch Types, N+1 Problem, Fetch Join & @EntityGraph
Default Fetch Types Per Relationship
RelationshipDefault Fetch Type
@OneToManyLAZY
@ManyToManyLAZY
@ManyToOneEAGER
@OneToOneEAGER
Rule of thumb: override @ManyToOne / @OneToOne to LAZY explicitly in most real projects, since their EAGER default is a common source of unwanted extra queries.
LAZY vs EAGER
LAZY ⭐
Load related entity only when needed — better performance, less memory, recommended for most relationships
EAGER
Load related entity immediately with parent — extra queries, slower performance, more memory
LazyInitializationException
Cause
Occurs when a lazy entity is accessed outside an active transaction — common cause: the session/transaction is closed before the child entity is loaded.
How To Avoid It
Use Fetch Join
Use @EntityGraph
Use DTO Projection
Access the entity inside the transaction
Don't just switch everything to EAGER
N+1 Query Problem & Solutions
Load Departments → 1 Query
Loop Departments → Load Employees → N Queries
Total = 1 + N Queries → Slow, High DB Load, Poor Scalability
Fetch Strategy Comparison
StrategyBehavior
LAZYBest performance, default choice
EAGERImmediate load — use carefully
Fetch Join (JPQL JOIN FETCH)Loads parent + child in a single query — recommended, eliminates N+1
@EntityGraphSpecifies related entities to load without changing the default fetch strategy — controlled fetching at the repository level
9. Querying — Derived, JPQL, Native, Specifications & Criteria API
Derived Query
Query generated from method name
JPQL
Object-oriented query on entities
Native SQL
Database-specific SQL
@NamedQuery
Reusable predefined JPQL
Specifications
Dynamic, type-safe query building
Criteria API
Programmatic dynamic query without JPQL
Derived Query Methods & Common Keywords
Examples
findByEmail(), findByStatus(), findByUsernameAndRole(), findByAgeGreaterThan(), findByNameContaining()
Common Derived Keywords
And, Or, Between, Like, Containing, StartingWith, EndingWith, In, OrderBy
JPQL vs SQL vs Native Query
JPQL
Queries Entities & Fields, database independent, portable, object-oriented, preferred by default
Native Query
Queries Tables & Columns directly, database specific, more powerful — use for complex SQL, stored procedures, vendor functions, DB optimization
@NamedQuery — predefined JPQL attached to an entity, executed by name; reusable, validated at startup, better organization. @Query — write custom JPQL or Native SQL directly inside the repository, supports parameters.
Specifications & Criteria API
Specifications
Dynamic, type-safe query building using the Criteria API. Use cases: dynamic filters, search screens, optional parameters, enterprise reporting.
Criteria API
Programmatic API for building dynamic queries without writing JPQL. Advantages: dynamic, type safe, flexible.
Pagination Flow
Client → Page = 0, Size = 20
Repository → LIMIT / OFFSET
Database → Page Result
Page vs Slice
Page
Contains content, total elements, total pages, current page, hasNext/hasPrevious — includes an extra COUNT query
Slice
Contains content and hasNext only, no total count — faster, better for large tables / infinite scrolling
Sorting examples: Name ASC, CreatedDate DESC, Salary ASC — applied via a Sort object → ORDER BY → sorted result.
11. Transactions, Propagation, Isolation & Concurrency
Atomicity
All or nothing
Consistency
Valid state
Isolation
Concurrent safety
Durability
Permanent storage
@Transactional Flow
Method Starts → Transaction Begins
Database Operations
↓ Success
Commit
↓ Failure
Rollback
@Transactional benefits: automatic commit, automatic rollback, declarative transaction management.
Propagation Types
REQUIRED ⭐ (Default)Join existing transaction, or create new
REQUIRES_NEWSuspend current, start a new transaction
SUPPORTSJoin if exists, otherwise non-transactional
NOT_SUPPORTEDExecute without a transaction
MANDATORYMust have an existing transaction
NEVERFails if a transaction exists
NESTEDNested transaction using savepoints
Isolation Levels & Concurrency Problems
Isolation Levels
READ_UNCOMMITTED → allows dirty reads READ_COMMITTED ⭐ → prevents dirty reads (default in many databases) REPEATABLE_READ → prevents non-repeatable reads SERIALIZABLE → highest isolation, lowest concurrency
Common Concurrency Problems
Dirty Read → reads uncommitted data Non-Repeatable Read → same row, different values on re-read Phantom Read → new rows appear during a transaction
Read-Only Transactions & Rollback Rules
Read-Only Transaction
Optimizes read operations. Benefits: better performance, prevents accidental updates, database optimization.
Rollback Rules
Default: rolls back on RuntimeException and Error. A checked exception does NOT trigger rollback unless explicitly configured.
12. Locking — Optimistic, Pessimistic & Deadlocks
Optimistic Locking
Assumes conflicts are rare — checks a @Version column before update. No immediate lock, higher performance, best for read-heavy systems.
Pessimistic Locking
Locks the database row immediately to prevent other transactions from modifying it. Lower concurrency, best for high-conflict systems.
Optimistic Lock Flow
User A reads Version = 1 | User B reads Version = 1
User A updates → Version = 2
User B updates → Version Mismatch → OptimisticLockException
@Version — maintains the entity version automatically for optimistic locking. Benefits: prevent lost updates, high concurrency, better performance.
Lock Modes
OPTIMISTICVersion check
OPTIMISTIC_FORCE_INCREMENTIncrement version
PESSIMISTIC_READRead lock
PESSIMISTIC_WRITEExclusive write lock
PESSIMISTIC_FORCE_INCREMENTWrite lock + version increment
Deadlock & How To Avoid It
Deadlock Example
Transaction A locks Row 1, needs Row 2
Transaction B locks Row 2, needs Row 1 → Deadlock
How To Avoid Deadlock
Access tables in the same order
Keep transactions short
Commit quickly
Avoid long locks
Use proper indexes
13. HikariCP Connection Pooling
Why Connection Pool?
Without Pool → New Connection Every Request → Slow
With Pool → Reuse Existing Connections → Fast
HikariCP — Default Pool In Spring Boot
Flow: Application → Request Connection → HikariCP → Available Connection → Database → Return Connection → Pool. Important settings: maximumPoolSize, minimumIdle, connectionTimeout, idleTimeout, maxLifetime
14. Caching Levels
First-Level Cache
Scope: one EntityManager / one transaction. Automatically enabled — no configuration needed.
Second-Level Cache
Scope: application-wide, shared across multiple sessions. Optional — requires a cache provider (Ehcache, Caffeine, Infinispan).
Query Cache
Stores query results alongside the second-level cache — reduces repeated database queries.
15. JDBC Batch Processing
Batch Processing Flow
100 Inserts
Hibernate Batch → Single Database Round Trip
Better Performance
Benefits of batching: fewer network calls, faster inserts, faster updates, lower database load. Execute multiple SQL statements together instead of one by one.
16. Performance Tuning & Production Checklist
Common Performance Problems
N+1 Queries
Too many SQL statements — fix with Fetch Join / @EntityGraph
EAGER Fetching
Loads unnecessary data
Missing Pagination
Huge result sets in memory
Long Transactions
Lock contention
Missing Indexes
Slow queries
Too Many Flushes
Extra SQL execution
Hibernate Performance Tuning & Production Checklist
Use LAZY Loading
Solve N+1 via Fetch Join / EntityGraph
Use Pagination
Enable JDBC Batch
Keep Transactions Short
Monitor SQL Logs (dev only)
Index Frequently Queried Columns
Fetch Only Required Columns Using DTO Projection
Avoid Unnecessary saveAndFlush()
Use Connection Pooling
Use Optimistic Locking
Use Specifications For Dynamic Search
Tune Pool Size
Disable Verbose SQL Logging In Production
Cache Frequently Accessed Data Carefully
17. Top Interview Differences
JPA vs Hibernate
Hibernate vs Spring Data JPA
CrudRepository vs JpaRepository
persist() vs merge()
find() vs getReference()
save() vs saveAndFlush()
Flush vs Commit
Transient vs Persistent vs Detached vs Removed
Owning Side vs Inverse Side
Cascade vs Orphan Removal
LAZY vs EAGER
JPQL vs SQL vs Native Query
Page vs Slice
Optimistic vs Pessimistic Locking
First-Level vs Second-Level Cache
Propagation REQUIRED vs REQUIRES_NEW
Dirty Read vs Non-Repeatable Read vs Phantom Read
Fetch Join vs @EntityGraph
Specifications vs Criteria API
@NamedQuery vs @Query
18. Real Project Scenarios
CertifyHub — User Entityapp_user Table; UserRepository extends JpaRepository → CRUD APIs
Update Profilefind() → Modify Name → Commit → Dirty Checking → UPDATE (no explicit save needed)
Large Batch Importsave() → Flush At Commit
Generate CertificatesaveAndFlush() → Need Generated ID Immediately
Course → Modules@OneToMany
Student ↔ Courses@ManyToMany
Course List Needing ModulesUse Fetch Join instead of N+1 queries
Dashboard — Users With RolesUse @EntityGraph
Search UsersSpecifications → Dynamic Filters
Monthly ReportsNative Query → Database Functions
Create User + Audit LogREQUIRES_NEW → Audit commits independently
Certificate UpdateOptimistic Locking → Prevent concurrent updates
Admin ReportPagination + Batch Processing → Fast Response
Bulk Student ImportJDBC Batch → Thousands Of Inserts
ProductionHikariCP → Reusable Connections → Better Throughput
19. Interview One-Liner Revision
ORM → Object Relational Mapping
JPA → Persistence Specification
Hibernate → JPA Implementation
Spring Data JPA → Repository Abstraction
Entity → Table Mapping
Repository → Data Access Layer
CrudRepository → Basic CRUD
JpaRepository → Full JPA Repository
EntityManager → JPA Core Interface
Persistence Context → First-Level Cache
Persistence Unit → JPA Configuration
Transient → New Object
Persistent → Managed Entity
Detached → Unmanaged Entity
Removed → Marked For Delete
persist() → Insert New Entity
merge() → Update / Reattach Entity
find() → Immediate Fetch
getReference() → Lazy Proxy
Dirty Checking → Automatic Update
Flush → Sync SQL
Commit → Permanent Save
mappedBy → Inverse Side
Owning Side → Controls Relationship
Cascade → Parent Operation Propagation
Orphan Removal → Delete Orphan Child
LAZY → Load On Demand
EAGER → Load Immediately
LazyInitializationException → Lazy Access Outside Transaction
N+1 → One Plus N Queries
Fetch Join → Single Query Fetch
@EntityGraph → Controlled Fetch Strategy
JPQL → Entity Query Language
Native Query → Database SQL
Specifications → Dynamic Query
Criteria API → Programmatic Query
Page → Total Count
Slice → No Count
Propagation → Nested Transaction Rules
Isolation → Concurrency Control
ReadOnly → Optimized Read Transaction
Optimistic Lock → Version Based
Pessimistic Lock → Database Lock
Deadlock → Circular Waiting
HikariCP → Connection Pool
First-Level Cache → Session Cache
Second-Level Cache → Shared Cache
Query Cache → Cached Query Results
JDBC Batch → Bulk SQL Execution
DTO Projection → Fetch Required Fields
20. 15-Minute Final Revision Flow
ORM → JPA → Hibernate → Spring Data JPA
Entity → JpaRepository → EntityManager → Persistence Context
Entity Lifecycle → Dirty Checking → Flush → Commit
Relationships → Cascade → Fetch Types → N+1 → Fetch Join → EntityGraph
JPQL → Native Query → Specifications → Pagination
Transactions → Propagation → Isolation → Optimistic Lock → Pessimistic Lock
HikariCP → Batch Processing → Caching → Performance Tuning
5–7 Years Interview Mantra — Interviewers Expect You To Explain
✓ Why, not just What (Specification vs Implementation, JPA vs Hibernate vs Spring Data JPA) ✓ Entity lifecycle internals — Transient/Persistent/Detached/Removed and what triggers each transition ✓ How to detect and fix N+1 — Fetch Join, @EntityGraph, DTO Projection ✓ Transaction management — Propagation, Isolation, Rollback rules, with real production examples ✓ Locking strategy trade-offs — Optimistic vs Pessimistic, when to use each ✓ Performance tuning — indexing, pagination, batching, connection pool sizing ✓ Real production issues you've faced with Hibernate/JPA and how you fixed them