50+ Advanced Hibernate & Spring Data JPA Interview Questions
If you are preparing for a senior Java Backend developer interview, reciting basic definitions won't cut it. Interviewers want to know if you understand how Hibernate operates under the hood, how it impacts database performance, and how you solve real-world scalability issues.
In this massive, in-depth guide by Spring Java Lab, we cover every critical question you need to know, grouped logically from architecture basics to 5-10 year experience bonus questions.
📺 Prefer Visual Learning?
Watch our full Hibernate & Spring Data JPA Interview Questions playlist on YouTube, explained step-by-step using clear infographic diagrams!
1. Hibernate Basics
What is Hibernate? How is it different from JDBC?
Hibernate is an Object-Relational Mapping (ORM) framework that maps Java objects (entities) to database tables. JDBC is the native Java API used to connect and execute raw SQL against a database.
Differences:
- Abstraction: JDBC requires manual SQL creation, connection handling, and
ResultSetparsing. Hibernate abstracts this away, generating SQL dynamically based on the configured database Dialect. - Performance: JDBC is generally faster for raw execution because it lacks the overhead of entity tracking, caching, and reflection that Hibernate relies on.
- Features: Hibernate provides out-of-the-box features like caching, lazy loading, and dirty checking, which must be built manually in JDBC.
What are the advantages and disadvantages of Hibernate?
Advantages: Database independence (switching from MySQL to PostgreSQL requires only a dialect change), automatic schema generation, reduced boilerplate code, caching mechanisms, and powerful querying (HQL/Criteria).
Disadvantages: Steep learning curve, overhead/slower performance for massive batch operations compared to JDBC, and the high risk of hidden performance pitfalls (like the N+1 problem) if relationships aren't configured correctly.
What is ORM (Object Relational Mapping)?
ORM is a programming technique used to convert data between incompatible type systems—specifically, object-oriented programming languages (Java) and relational databases (SQL). It allows developers to interact with the database using objects and methods rather than writing database-specific SQL strings.
Explain the Hibernate architecture. What are SessionFactory, Session, Transaction, and Configuration?
- Configuration: Reads the properties (e.g.,
hibernate.cfg.xmlor Spring'sapplication.properties) and mapping files to build the SessionFactory. - SessionFactory: A heavy-weight, thread-safe, immutable object created once per database during startup. It acts as a factory for Sessions and holds the Second-Level Cache.
- Session: A light-weight, non-thread-safe object representing a single conversation with the database. It maintains the First-Level Cache and the Persistence Context.
- Transaction: Represents a unit of work. It abstracts the underlying JDBC/JTA transaction management.
2. Entity Lifecycle
What are the different states of a Hibernate entity? (Transient, Persistent, Detached, Removed)
The core of Hibernate revolves around the Persistence Context. An entity can be in one of four states:
- Transient: A newly created object (via
newkeyword) that has never been associated with a Session and has no database representation. - Persistent (Managed): An object currently associated with an active Session. Hibernate tracks all changes to this object (Dirty Checking) and will synchronize them with the database upon
flush(). - Detached: An object that was previously persistent, but the Session it belonged to was closed or cleared. Changes to this object are not tracked.
- Removed: A persistent object passed to
session.remove(). It remains managed but is scheduled for deletion in the database at commit time.
What is the difference between save(), persist(), saveOrUpdate(), update(), and merge()?
- persist() [JPA Standard]: Transitions a transient entity to persistent. It does not guarantee an immediate return of the generated identifier; execution may be deferred until flush time. Cannot be called on detached entities.
- save() [Hibernate Native]: Similar to persist, but guarantees the immediate return of the generated identifier (Serializable).
- update() [Hibernate Native]: Reattaches a detached entity to a session. Throws an exception if another entity with the same ID is already in the session.
- merge() [JPA Standard]: Copies the state of a detached entity onto a persistent entity with the same ID. It returns the managed instance. The original object passed in remains detached.
- saveOrUpdate() [Hibernate Native]: Checks if the entity has an identifier. If no, it calls
save(). If yes, it callsupdate().
What is the difference between get() and load()?
Session.get() hits the database immediately (if the entity isn't in the L1 cache). It returns null if the record doesn't exist.
Session.load() (or EntityManager.getReference()) returns an uninitialized Proxy object without hitting the database. The SELECT query is only fired when you access a non-ID property (e.g., entity.getName()). If the record doesn't exist, it throws an ObjectNotFoundException.
What is the difference between save() and persist()?
As detailed above, save() is Hibernate-specific and immediately returns the generated ID (triggering an immediate INSERT if using IDENTITY generation), whereas persist() is the JPA standard and defers the SQL execution and ID generation (when possible) until the transaction flushes.
What is the difference between update() and merge()?
update() tries to make the passed object persistent directly. merge() copies the data from the passed object into a newly loaded persistent object, leaving the passed object detached. Use merge() when dealing with DTOs mapped back to entities in stateless REST APIs.
3. Fetching
What is the difference between FetchType.LAZY and FetchType.EAGER?
LAZY fetching defers loading the associated collection/entity until it is explicitly accessed. Hibernate assigns a Proxy to the field. EAGER fetching immediately retrieves the associated data along with the main entity using a SQL JOIN or a secondary SELECT query.
@OneToOne and @ManyToOne default to EAGER. @OneToMany and @ManyToMany default to LAZY.
What is the N+1 Query Problem? How do you solve it?
The N+1 problem occurs when you fetch a list of N parent entities (1 query) and then iterate through them to access a lazy-loaded relationship. Hibernate fires an additional query for every parent to fetch the children, resulting in N+1 total queries.
Solution: You can solve this using JOIN FETCH, @EntityGraph, or Batch Fetching.
What is Join Fetch? When should you use it?
JOIN FETCH is a JPQL/HQL keyword that tells Hibernate to retrieve the associated entities in the same single query using a SQL JOIN, fully initializing the collections and avoiding proxies. Use it when you know you will need the associated data immediately (e.g., serializing a full JSON response).
@Query("SELECT p FROM Post p JOIN FETCH p.comments")
List<Post> findAllWithComments();
What are Fetch Join, EntityGraph, and Batch Fetching?
- Fetch Join: (Same as Join Fetch above). Hardcoded in the JPQL query.
- EntityGraph: A JPA feature that allows you to dynamically define which lazy associations should be fetched eagerly for a specific repository method, without altering the base JPQL query.
- Batch Fetching: Configured via
@BatchSize(size=50)or properties. Instead of fetching children one by one, Hibernate collects the IDs of the parents and fetches the children using anIN (id1, id2, ... id50)clause.
4. Caching
What is the First-Level Cache?
The First-Level Cache is tied to the Session. It is enabled by default and cannot be disabled. When you fetch an entity by its ID, Hibernate stores it here. If you request the same ID within the same transaction, Hibernate returns it from memory without hitting the database.
What is the Second-Level Cache?
The Second-Level Cache (L2) is tied to the SessionFactory and is shared across all sessions/transactions. It is disabled by default and requires a provider (like Ehcache, Redis, or Hazelcast). It stores entities (as destructured arrays, not actual objects) to drastically reduce read queries for reference data.
What is the Query Cache?
The Query Cache stores the results of JPQL queries. However, it only stores the IDs of the returned entities, not the entities themselves. Therefore, it must be used in conjunction with the Second-Level Cache. Otherwise, hitting a cached query would result in N queries to fetch the actual entities based on the cached IDs!
Difference between First-Level Cache and Second-Level Cache?
First-level is session-scoped, enabled by default, and isolated to a single transaction. Second-level is application-scoped (SessionFactory), shared across all users/transactions, disabled by default, and requires an external caching provider.
5. Relationships
Explain all JPA/Hibernate relationships.
- OneToOne: A single entity is related to a single instance of another entity (e.g.,
UsertoUserProfile). - OneToMany: One entity has a collection of other entities (e.g.,
DepartmenttoEmployees). - ManyToOne: Many entities belong to one entity. This is the most common relationship and the one that typically holds the Foreign Key.
- ManyToMany: Many records relate to many records, requiring a physical Join Table in the database (e.g.,
StudentsandCourses).
Difference between Unidirectional and Bidirectional Mapping?
In Unidirectional, only one entity knows about the relationship (e.g., Order has List<Item>, but Item doesn't know about Order). In Bidirectional, both entities hold references to each other, allowing navigation in both directions.
What is mappedBy? Why is it required?
In a bidirectional relationship, the database only has one foreign key. mappedBy is placed on the inverse (non-owning) side to tell Hibernate: "I do not own this relationship. Look at the field named 'X' on the other entity to figure out how to map this to the database." If omitted, Hibernate will incorrectly assume two separate relationships and create redundant mapping tables.
What is Cascade? Explain all Cascade Types.
Cascading propagates entity state transitions from a parent to its children.
- PERSIST: Saving the parent saves the children.
- MERGE: Merging the parent merges the children.
- REMOVE: Deleting the parent deletes the children.
- REFRESH: Refreshing the parent refreshes the children from the DB.
- DETACH: Detaching the parent detaches the children.
- ALL: Applies all of the above.
What is Orphan Removal? How is it different from Cascade REMOVE?
CascadeType.REMOVE only triggers when you delete the parent entity itself.
orphanRemoval = true handles the scenario where a parent still exists, but a child is removed from the collection (parent.getChildren().remove(child)). Hibernate detects that the child is now an "orphan" and automatically deletes it from the database.
6. Transactions & Performance
What is the difference between flush() and commit()?
flush() synchronizes the in-memory state of the Persistence Context with the database by executing queued SQL statements (INSERT/UPDATE/DELETE). It does not finalize the database transaction.
commit() issues the actual database commit command, making the changes permanent. A commit automatically triggers a flush right before it executes.
How can you improve Hibernate performance?
Answering this effectively shows senior-level expertise. Here are the 10 pillars:
- Lazy Loading: Default all relationships to LAZY to avoid fetching massive object graphs unnecessarily.
- Join Fetch: Use it strategically for use cases where you know you need the child data, avoiding the N+1 problem.
- Batch Fetching: Enable
@BatchSizeordefault_batch_fetch_sizeto optimize fetching collections. - Batch Inserts/Updates: Configure
spring.jpa.properties.hibernate.jdbc.batch_size=50to send multiple inserts in a single network round-trip. - Second-Level Cache: Cache static reference data (like Country codes or Categories).
- Proper Indexing: Ensure foreign keys and heavily queried columns have database-level indexes.
- DTO Projection: Don't fetch full entities if you only need 2 columns. Use Spring Data Interface Projections or custom JPQL to return DTOs directly, bypassing the persistence context entirely.
- Pagination: Never load thousands of records into memory. Use
Pageablein Spring Data. - Avoid N+1: Constantly monitor SQL logs to ensure loops aren't triggering subsequent queries.
- JDBC Batch Size: Align the Hibernate batch size with your database driver's optimal packet size.
7. Bonus Questions (Frequently Asked for 5–10 Years Experience)
What is dirty checking?
Dirty checking is the mechanism by which Hibernate automatically detects modifications to managed entities. If you change a setter on an entity loaded in an active session, Hibernate will automatically generate and execute an UPDATE statement at flush time. You don't need to call save().
How does Hibernate dirty checking work internally?
When Hibernate loads an entity into the Session, it takes a deep-copy snapshot of its state array. During the flush phase, it iterates over all managed entities and compares their current state against the original snapshot. If differences are found, it generates the appropriate SQL. (Note: Using bytecode enhancement, Hibernate can intercept setter calls directly instead of comparing arrays, which is faster for massive sessions).
What is optimistic locking?
A concurrency strategy that assumes multiple transactions won't conflict often. It doesn't lock the database row. Instead, it relies on a version column. When an update happens, it checks if the version in the database matches the version the transaction read. If they differ, an OptimisticLockException is thrown.
What is pessimistic locking?
Assumes conflicts are highly likely. It explicitly locks the database row using SQL constructs like SELECT ... FOR UPDATE. Other transactions must wait until the lock is released.
What is @Version?
An annotation used to enable Optimistic Locking. You place it on an integer, long, or timestamp field. Hibernate automatically increments this value on every update.
@Version
private Integer version;
What is @Transactional?
A Spring annotation that manages database transactions via AOP (Aspect-Oriented Programming). It wraps the annotated method in a proxy, starting a transaction before the method executes, and committing (or rolling back on RuntimeExceptions) when the method completes.
Difference between flush() and clear()?
flush() sends SQL to the database to sync the state. clear() wipes the First-Level Cache entirely, detaching all managed entities. Using flush() followed by clear() is standard practice when processing massive batches to prevent OutOfMemoryError.
What is the Persistence Context?
It is the runtime environment (represented by the Session/EntityManager) where entity instances are managed. It acts as the First-Level Cache and the engine for dirty checking and lifecycle state transitions.
What are JPQL and HQL?
JPQL (Java Persistence Query Language) and HQL (Hibernate Query Language) are object-oriented query languages. Instead of querying database tables and columns, you query Java Entity classes and their properties.
Difference between JPQL, HQL, and Native SQL?
JPQL is the JPA standard. HQL is Hibernate's extension (superset) of JPQL. Native SQL is raw, database-specific SQL (e.g., PostgreSQL specific syntax) which bypasses object mapping unless explicitly mapped to a @SqlResultSetMapping.
What is Criteria API?
A programmatic, type-safe API for building dynamic queries. Instead of writing JPQL strings, you use Java objects and methods to construct the query, preventing runtime syntax errors and making dynamic filtering much easier.
What is EntityManager?
The core interface of the JPA specification used to interact with the Persistence Context (equivalent to Hibernate's Session).
Difference between EntityManager and Session?
EntityManager is the standard JPA interface. Session is the proprietary Hibernate implementation. Spring Boot uses JPA by default, but you can unwrap the EntityManager to get the Hibernate Session if you need Hibernate-specific features.
What is @NamedQuery?
A statically defined JPQL query attached to an entity class. It is validated and precompiled at application startup, providing a slight performance boost and keeping query logic close to the entity.
What is @Embeddable and @Embedded?
Used for grouping related fields into a reusable component (Value Object) without creating a separate database table. For example, an Address class annotated with @Embeddable can be included in a User entity using @Embedded, flattening the address fields into the user table.
What is Composite Primary Key (@EmbeddedId vs @IdClass)?
Used when a table's primary key consists of multiple columns. @IdClass applies a separate class to represent the key fields directly in the entity. @EmbeddedId uses an @Embeddable class as a single field in the entity to represent the key.
Difference between GenerationType.IDENTITY, SEQUENCE, TABLE, and AUTO?
- IDENTITY: Relies on database auto-increment. Warning: Disables Hibernate's JDBC batch inserts because Hibernate must execute the insert immediately to get the ID.
- SEQUENCE: Uses database sequences. Highly optimized, supports batching, preferred for PostgreSQL/Oracle.
- TABLE: Simulates a sequence using a separate database table. Very slow, avoid if possible.
- AUTO: Lets Hibernate choose based on the Dialect (usually defaults to SEQUENCE in modern Hibernate).
What is JDBC batching in Hibernate?
A performance feature where Hibernate groups multiple INSERT, UPDATE, or DELETE statements into a single network call to the database, drastically reducing latency during bulk operations.
What is Open Session in View (OSIV)?
A pattern (enabled by default in Spring Boot) that keeps the Hibernate Session open until the web request is fully rendered. This allows lazy-loading in the View/Controller layer. Anti-pattern warning: It holds database connections open too long and masks N+1 problems. It should usually be disabled via spring.jpa.open-in-view=false.
Why do we get LazyInitializationException?
Thrown when you attempt to access a LAZY proxy object after the transaction (Session) has been closed. Since the session is gone, Hibernate cannot connect to the database to fetch the missing data.
Difference between delete() and remove()?
They do the same thing. delete() is the older Hibernate Session method, while remove() is the standard JPA EntityManager method.
What are interceptors and event listeners?
Mechanisms to execute custom logic at specific points in the entity lifecycle. Examples include automatically setting `createdAt` or `updatedAt` timestamps just before an entity is saved (e.g., using @PrePersist and @PreUpdate).
How does Hibernate generate SQL?
Hibernate uses the configured Dialect (e.g., PostgreSQLDialect) to translate JPQL/Criteria queries and entity state changes into the specific, optimized native SQL syntax understood by your target database.
What is bytecode enhancement?
A build-time or load-time process where Hibernate modifies the compiled .class files of your entities to inject optimized code for lazy loading (even for basic properties), dirty checking (intercepting setters directly), and creating no-arg constructors.
How do you enable SQL logging in Hibernate?
In your application.properties:
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
# For binding parameters (the "?" values):
logging.level.org.hibernate.orm.jdbc.bind=TRACE
8. Additional Frequently Asked Hibernate Interview Questions
What is the owning side of a relationship?
In a bidirectional relationship, the owning side contains the foreign key and does not use mappedBy. Hibernate only considers changes made on the owning side when synchronizing the relationship with the database.
What is a Hibernate Proxy?
A Hibernate Proxy is a dynamically generated subclass used for lazy loading. It delays fetching entity data until a non-identifier property is accessed.
Why should you avoid FetchType.EAGER?
EAGER fetching can create unnecessarily large object graphs, trigger additional SQL queries, increase memory usage, and contribute to the N+1 problem. Prefer LAZY and fetch associations explicitly when required.
Difference between Entity and DTO?
Entities are managed by Hibernate and mapped to database tables. DTOs are simple objects used to transfer data between layers or APIs. Returning DTOs avoids exposing persistence details and improves performance.
Why use DTO Projection?
DTO projections retrieve only the required columns instead of entire entities, reducing memory consumption and avoiding unnecessary lazy loading.
How do you prevent SQL Injection in Hibernate?
Hibernate uses prepared statements and parameter binding for JPQL, Criteria API, and repository methods. Avoid string concatenation while building queries.
What is @BatchSize?
@BatchSize instructs Hibernate to load multiple lazy associations in batches using an IN (...) clause, reducing the number of SQL queries.
Why doesn't JDBC batching work with GenerationType.IDENTITY?
IDENTITY requires executing each INSERT immediately to obtain the generated primary key, preventing Hibernate from grouping multiple INSERT statements into a batch.
Difference between CrudRepository and JpaRepository?
CrudRepository provides basic CRUD operations, whereas JpaRepository extends it with JPA-specific features such as flushing, batch operations, pagination support, and more.
Difference between findById() and getReferenceById()?
findById() immediately queries the database and returns an Optional. getReferenceById() returns a lazy proxy that is initialized only when required.
What is Hibernate Dialect?
A Dialect tells Hibernate how to generate SQL optimized for a specific database such as Oracle, PostgreSQL, MySQL, or SQL Server.
Difference between evict() and clear()?
evict() removes a single entity from the first-level cache, whereas clear() removes all managed entities from the persistence context.
What are @DynamicInsert and @DynamicUpdate?
These Hibernate annotations generate SQL containing only the required columns, reducing unnecessary updates and allowing database defaults to be applied.
What is @MappedSuperclass?
@MappedSuperclass allows common persistent fields to be inherited by entities without creating a separate table.
What are Hibernate Statistics?
Hibernate Statistics provide metrics such as executed queries, cache hits, cache misses, and entity operations, helping identify performance bottlenecks.
🚀 Explore More Java Interview Resources
Continue your interview preparation with our comprehensive Java roadmaps, covering everything from core fundamentals to senior-level system design.
☕ Top Java Questions for Freshers
Essential Core Java questions, collections, and exception handling every fresher must prepare before their first interview.
⚡ Advanced Java Concurrency
High-level concurrency questions, threads, locks, and synchronization concepts frequently asked in senior developer interviews.
🏗️ System Design Interviews
Master microservices, scalability, and real-world Java system design scenarios to crack architect-level rounds.