Spring Boot JPA – Architecture (Part 2)

JPA is not magic. Behind the scenes, Spring Boot creates and wires several components that work together whenever your API hits the database.
Let’s understand what really happens.
1. ORM Architecture
Flow:
Application → JPA → Hibernate → JDBC → DB Driver → Database
ORM (Object Relational Mapping) acts as a bridge between Java objects and database tables.
Instead of writing SQL:
- Tables → Entities
- Rows → Objects
- Queries → Method calls
2. A Simple JPA Flow
When you call repository.save(user):
- Spring gets an EntityManager
- Entity is placed in Persistence Context
- SQL is generated by Hibernate Dialect
- JDBC executes it
- Driver talks to DB
You only write Java — Hibernate handles SQL.
3. JPA Core Components
a) Persistence Unit
A logical group of entities that share:
- Database config
- JPA provider
- Dialect
Spring Boot configures this using application.properties.
b) EntityManagerFactory
- Created once at startup
- One per Persistence Unit
- Creates EntityManager objects
- Heavy object
Spring internally uses LocalContainerEntityManagerFactoryBean.
c) EntityManager
This is your main JPA engine.
Methods:
persist()→ insertmerge()→ updatefind()→ selectremove()→ deletecreateQuery()→ JPQL
EntityManager works with Persistence Context.
4. Persistence Context
Think of it as first-level cache.
- Holds managed entities
- Tracks changes
- Syncs to DB during commit
- Controls entity lifecycle
Entity States
NEW → MANAGED → REMOVED
↘ DETACHED ↗
| State | Meaning |
|---|---|
| New | Not saved |
| Managed | Tracked by JPA |
| Detached | Not tracked |
| Removed | Scheduled for delete |
5. Transaction Manager
Transaction manager binds EntityManager with DB transaction.
Two types:
- RESOURCE_LOCAL → Single DB
- JTA → Multiple DB (distributed)
Spring auto-creates it based on config.
6. @Transactional Matters
EntityManager write operations must be inside a transaction.
Without @Transactional:
entityManager.persist(user); // ERROR
With:
@Transactional
public void save(User user) {
entityManager.persist(user);
}
Now JPA opens transaction, commits, flushes SQL.
7. JpaRepository & Transactions
Spring Data internally annotates:
- save()
- delete()
- update()
with @Transactional.
That’s why they work even when you don’t add it.
8. Dialect
Hibernate uses Dialect to convert JPQL into DB-specific SQL.
Examples:
- MySQL →
MySQLDialect - H2 →
H2Dialect - PostgreSQL →
PostgreSQLDialect
9. H2 Console
Enable:
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
EXTRA REAL-WORLD NOTES
- EntityManager is not thread-safe
- PersistenceContext is per transaction
- flush() syncs SQL before commit
- clear() removes cache
- Dirty checking auto updates DB
INTERVIEW QUESTIONS
Q1. What is Persistence Context?
First-level cache that manages entity lifecycle.
Q2. Difference between EntityManager & EntityManagerFactory?
Factory creates managers; manager performs CRUD.
Q3. Why is @Transactional required?
To bind JPA operations to DB transactions.
Q4. What is Hibernate Dialect?
Maps JPQL to database-specific SQL.
Q5. Difference between merge() and persist()?
| persist | merge |
|---|---|
| New entity | Detached entity |
| Insert | Update |
Q6. What happens if transaction is missing?
Exception: No EntityManager with actual transaction available.