JPA and Hibernate Interview Questions for Java Full Stack with React
25 JPA and Hibernate questions with answers for java full stack with react roles — 5 easy, 13 medium, 7 hard.
About JPA and Hibernate
JPA with Hibernate and Spring Data JPA connects Java objects to relational tables. This topic covers entity mapping, relationships, entity states, lazy and eager loading, the N+1 problem, caching, optimistic locking, pagination, projections, Specifications and schema migrations with Flyway. Performance questions here are very common because ORM misuse is a frequent cause of slow production APIs.
Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
What is the difference between JPA, Hibernate and Spring Data JPA?
JPA, now Jakarta Persistence, is a specification that defines annotations and the EntityManager API for object-relational mapping. Hibernate is the most widely used implementation of that specification and adds extra features. Spring Data JPA is a layer above JPA that generates repository implementations from interfaces, so methods like findByEmail are created automatically. In a Spring Boot app you write against Spring Data, which uses JPA, which is implemented by Hibernate.
02
How do derived query methods work in Spring Data JPA?
Spring Data parses the method name in a repository interface and builds the query. For example, findByEmailAndActiveTrue(String email) or findTop5ByCategoryOrderByPriceDesc(String category). Supported keywords include And, Or, Between, LessThan, Like, In, IsNull and OrderBy. Return types can be Optional, List, Page or Stream. For complex logic, use @Query with JPQL or native SQL, because very long method names become hard to read.
03
What are the options for spring.jpa.hibernate.ddl-auto and which should be used in production?
none does nothing, validate checks that the schema matches entities, update alters tables to add missing columns, create drops and recreates the schema at startup and create-drop also drops it at shutdown. update and create are fine for learning but risky in production because they cannot handle renames or data migrations safely. In production use validate or none, and manage schema changes with Flyway or Liquibase scripts.
04
Write a JPA entity for a Product with an auto-generated ID and basic constraints.
I start with the official getting-started guide and build a tiny working example, then read how it is used in our codebase. For example, when our team adopted Flyway, I created a sample project, tried failure cases like a bad migration and wrote a one-page guide for the team. Within a week I was handling migrations in the main project. I also note questions and clarify them with seniors early instead of guessing.
A new or transient entity is just a Java object not known to the persistence context. A managed entity is attached to the context; changes are tracked and flushed automatically through dirty checking. A detached entity was managed but the context has closed, so changes are not tracked unless you merge it. A removed entity is scheduled for deletion on flush. Understanding these states explains why setters inside a transaction update the database without calling save.
07
What is the difference between lazy and eager fetching?
Lazy fetching loads an association only when it is first accessed, using a proxy. Eager fetching loads it immediately with the parent. By default, @OneToMany and @ManyToMany are lazy, while @ManyToOne and @OneToOne are eager. Best practice is to make all associations lazy and fetch what each use case needs with JOIN FETCH or entity graphs, because eager loading often pulls large object graphs and causes extra queries.
08
What is the N+1 select problem and how do you solve it?
It happens when one query loads N parent rows and then each lazy association fires a separate query, giving N+1 queries. For example, listing 100 orders and calling getCustomer on each. Solve it with JOIN FETCH in JPQL, @EntityGraph on the repository method, batch fetching with hibernate.default_batch_fetch_size, or DTO projections that select only the needed columns. Enable SQL logging or a statistics tool in development to catch it early.
09
What is the difference between persist and merge, and between save and saveAndFlush?
persist makes a new entity managed and assigns its ID; it fails for detached entities. merge copies the state of a detached entity onto a managed copy and returns that copy. Spring Data save calls persist for new entities and merge otherwise. saveAndFlush also calls flush, pushing pending SQL to the database immediately, which helps when you need a constraint error or trigger result now. The commit still happens at the end of the transaction.
10
In a bidirectional @OneToMany relationship, what does mappedBy mean?
mappedBy marks the inverse side and names the field on the other entity that owns the relationship. The owning side, usually the @ManyToOne with the foreign key column, is the one Hibernate uses to write the join column. For example, Order has @OneToMany(mappedBy = "order") and OrderItem has @ManyToOne @JoinColumn(name = "order_id"). Always update both sides in helper methods such as addItem to keep the object graph consistent.
11
What causes LazyInitializationException and how do you fix it properly?
It occurs when a lazy association is accessed after the persistence context has closed, for example in a controller or during JSON serialisation outside the transaction. The proper fix is to fetch the data inside the service transaction using JOIN FETCH or @EntityGraph and map it to a DTO. Avoid enabling spring.jpa.open-in-view as a crutch, and avoid switching associations to eager, because both hide performance problems.
12
Write a repository query that loads orders with their items in one query.
public interface OrderRepository extends JpaRepository<Order, Long> {
@Query("""
select distinct o from Order o
join fetch o.items i
where o.customer.id = :customerId
""")
List<Order> findWithItems(@Param("customerId") Long customerId);
@EntityGraph(attributePaths = {"items", "customer"})
Optional<Order> findWithGraphById(Long id);
}
13
Implement pagination and sorting for a product list API.
-- src/main/resources/db/migration/V3__add_sku_to_products.sql
ALTER TABLE products ADD COLUMN sku VARCHAR(40);
UPDATE products SET sku = CONCAT('SKU-', id) WHERE sku IS NULL;
ALTER TABLE products ALTER COLUMN sku SET NOT NULL;
CREATE UNIQUE INDEX ux_products_sku ON products (sku);
# application.yml
# spring.jpa.hibernate.ddl-auto: validate
# Flyway runs pending V-scripts in order at startup.
16
Returning an entity from a REST API causes infinite recursion in JSON. Why, and how do you fix it?
Bidirectional relationships, such as Order having items and each item referencing its order, make Jackson serialise back and forth endlessly, leading to StackOverflowError. The cleanest fix is to return DTOs instead of entities, so you control exactly what is exposed. Quick fixes include @JsonManagedReference with @JsonBackReference or @JsonIgnore on one side. DTOs also stop lazy loading during serialisation and avoid leaking internal fields.
17
The business wants deleted customers to be recoverable. How would you implement soft delete with JPA?
Add a deleted flag or deleted_at timestamp column. With Hibernate 6.4 and later you can annotate the entity with @SoftDelete, or use @SQLDelete to turn delete into an UPDATE and @SQLRestriction to filter deleted rows from queries. Unique constraints must account for deleted rows, for example a partial index on email where deleted is false. Provide an admin restore endpoint and a scheduled job to purge old records for data retention.
Cascade propagates operations from a parent to its children: PERSIST, MERGE, REMOVE, REFRESH, DETACH or ALL. For example, saving an Order with CascadeType.ALL also saves its items. orphanRemoval = true deletes a child row when it is removed from the parent's collection. Use them for true parent-child aggregates like order and items, but never cascade REMOVE on @ManyToOne or shared references like Category, or deleting one product could delete the category.
19
Explain the first-level and second-level cache in Hibernate.
The first-level cache is the persistence context itself. It is enabled by default and scoped to a session or transaction, so loading the same entity twice returns the same object without a second query. The second-level cache is optional and shared across sessions, configured with a provider like Ehcache or Infinispan through JCache. It suits read-mostly reference data. In clustered systems many teams prefer an explicit Redis cache at the service layer instead.
Add a numeric or timestamp field annotated with @Version. Hibernate includes it in the UPDATE where clause and increments it. If another transaction already changed the row, no rows match, and an OptimisticLockException is thrown. This prevents lost updates without holding database locks, which suits web apps with low conflict. The API can return HTTP 409 and ask the user to reload. Pessimistic locking with SELECT FOR UPDATE suits high-conflict cases like seat booking.
21
Build a dynamic search with optional filters using JPA Specifications.
Enable SQL logging or Hibernate statistics to confirm it is the N+1 problem, usually from lazy associations accessed while mapping entities to JSON. Fetch the required associations in one query with JOIN FETCH or @EntityGraph, or select a DTO projection with only the needed columns. For collections combined with pagination, page the parent IDs first and then fetch children with an IN query, or use batch fetch size. Add a test that asserts the query count.
23
Two admins edit the same product price at the same time and one change is silently lost. How do you prevent this?
This is a lost update. Add a @Version column for optimistic locking, send the version to the frontend with the entity, and include it in the update request. If the version no longer matches, Hibernate throws an optimistic lock exception, and the API returns HTTP 409 Conflict so the user can reload and retry. For short, high-contention operations like stock decrement, use a pessimistic lock or an atomic UPDATE with a condition.
24
Inserting one lakh rows with saveAll takes many minutes. How do you speed it up?
Enable JDBC batching with hibernate.jdbc.batch_size of 50 or so, plus order_inserts and order_updates. IDENTITY ID generation disables insert batching in Hibernate, so use a SEQUENCE generator with an allocation size on PostgreSQL or Oracle. Flush and clear the persistence context every batch to keep memory low. For very large loads, use JdbcTemplate batchUpdate or the database's bulk loader like COPY or LOAD DATA, which is much faster than ORM.
25
Describe a time you improved the performance of an application.
Situation: our dashboard API took eight seconds and users complained. Task: I was asked to bring it under one second. Action: using SQL logs and a profiler, I found N+1 queries and a missing index. I rewrote the query with a DTO projection, added a composite index and cached reference data with a short expiry. Result: response time dropped to about 400 milliseconds, and I added the query-count check to our test suite.
Frequently asked questions
How important is JPA and Hibernate in Java Full Stack with React interviews?
JPA with Hibernate and Spring Data JPA connects Java objects to relational tables. This topic covers entity mapping, relationships, entity states, lazy and eager loading, the N+1 problem, caching, optimistic locking, pagination, projections, Specifications and schema migrations with Flyway. Performance questions here are very common because ORM misuse is a frequent cause of slow production APIs.
How should I use the JPA and Hibernate sheet?
Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.