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
Specification, Standard API, Interfaces, Portable
Implementation, Framework, Concrete Classes, Feature Rich — uses EntityManager, manual repository code
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
| Repository | Provides |
| CrudRepository | CRUD Only |
| PagingAndSortingRepository | CRUD + 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
| Method | Purpose |
| 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()
New Entity, INSERT, fails if the entity already exists
Existing / Detached Entity, INSERT or UPDATE, returns a managed entity
Immediately loads the entity
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
Synchronizes Persistence Context with DB without ending the transaction — executes SQL, transaction still active, can still rollback
Flush → Ends transaction → Changes become permanent → Releases resources
save() vs saveAndFlush()
Saves entity, flush happens later at commit (default) — better performance
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.PERSIST→Parent saved → Child saved
CascadeType.MERGE→Parent updated → Child updated
CascadeType.REMOVE→Parent deleted → Child deleted
CascadeType.REFRESH→Parent reloaded → Child reloaded
CascadeType.DETACH→Parent detached → Child detached
CascadeType.ALL→Includes PERSIST, MERGE, REMOVE, REFRESH, DETACH
Orphan Removal & Cascade vs Orphan Removal
Deletes child when the parent is deleted
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
| Relationship | Default Fetch Type |
| @OneToMany | LAZY |
| @ManyToMany | LAZY |
| @ManyToOne | EAGER |
| @OneToOne | EAGER |
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
Load related entity only when needed — better performance, less memory, recommended for most relationships
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
| Strategy | Behavior |
| LAZY | Best performance, default choice |
| EAGER | Immediate load — use carefully |
| Fetch Join (JPQL JOIN FETCH) | Loads parent + child in a single query — recommended, eliminates N+1 |
| @EntityGraph | Specifies 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
Queries Entities & Fields, database independent, portable, object-oriented, preferred by default
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
Contains content, total elements, total pages, current page, hasNext/hasPrevious — includes an extra COUNT query
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
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_NEW→Suspend current, start a new transaction
SUPPORTS→Join if exists, otherwise non-transactional
NOT_SUPPORTED→Execute without a transaction
MANDATORY→Must have an existing transaction
NEVER→Fails if a transaction exists
NESTED→Nested 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
Assumes conflicts are rare — checks a @Version column before update. No immediate lock, higher performance, best for read-heavy systems.
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
OPTIMISTIC→Version check
OPTIMISTIC_FORCE_INCREMENT→Increment version
PESSIMISTIC_READ→Read lock
PESSIMISTIC_WRITE→Exclusive write lock
PESSIMISTIC_FORCE_INCREMENT→Write 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
Scope: one EntityManager / one transaction. Automatically enabled — no configuration needed.
Scope: application-wide, shared across multiple sessions. Optional — requires a cache provider (Ehcache, Caffeine, Infinispan).
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 Entity→app_user Table; UserRepository extends JpaRepository → CRUD APIs
Update Profile→find() → Modify Name → Commit → Dirty Checking → UPDATE (no explicit save needed)
Large Batch Import→save() → Flush At Commit
Generate Certificate→saveAndFlush() → Need Generated ID Immediately
Course → Modules→@OneToMany
Student ↔ Courses→@ManyToMany
Course List Needing Modules→Use Fetch Join instead of N+1 queries
Dashboard — Users With Roles→Use @EntityGraph
Search Users→Specifications → Dynamic Filters
Monthly Reports→Native Query → Database Functions
Create User + Audit Log→REQUIRES_NEW → Audit commits independently
Certificate Update→Optimistic Locking → Prevent concurrent updates
Admin Report→Pagination + Batch Processing → Fast Response
Bulk Student Import→JDBC Batch → Thousands Of Inserts
Production→HikariCP → 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