Hibernate & JPA Interview Questions

Hibernate and JPA interview questions: ORM mappings, caching, lazy loading, inheritance and transactions.

30 questions

1 What is the difference between JPA and Hibernate? EASY

JPA (Java Persistence API) is a specification - interfaces and annotations like @Entity, @Table and EntityManager. Hibernate is an implementation of that spec (the most popular JPA provider), plus additional native features such as HQL extensions and enhanced caching.

You should code against JPA interfaces so you can swap providers; Hibernate just happens to be the default in Spring Boot.

2 Explain the states of a Hibernate entity. MEDIUM
  • Transient - created with new, not associated with a session, no database row.
  • Persistent - associated with a session; changes are tracked and flushed to the database.
  • Detached - was persistent but the session has closed; changes are no longer tracked automatically (re-attach with merge).
  • Removed - marked for deletion, row deleted on flush.
3 What is the difference between get() and load()? MEDIUM

Both load an entity by id. get() fetches immediately and returns null if the row does not exist. load() returns a lazy proxy without hitting the database until a property is accessed, and throws ObjectNotFoundException if the row is missing.

Prefer get() when you need the data now or are not sure the row exists; load() helps avoid unnecessary queries for references.

4 Explain lazy loading and the N+1 query problem. HARD

Lazy loading defers loading a relationship until it is actually accessed by fetching a proxy. It avoids loading child collections you never use, but causes trouble outside an open session (LazyInitializationException).

The N+1 problem: querying N parents triggers N extra queries for their children. Fixes: join fetch in JPQL, EntityGraph/annotations, @BatchSize, or session management such as Spring Open Session in View.

5 What are the different inheritance mapping strategies? MEDIUM
  • SINGLE_TABLE - one table for the whole hierarchy with a discriminator column. Fast but wastes nullable columns.
  • TABLE_PER_CLASS - one table per concrete class. No nulls but polymorphic queries need UNION.
  • JOINED - a base table plus child tables joined by primary key. Normalised but more joins.

Choose based on query patterns: single table is usually the simplest default.

6 Explain the first-level and second-level cache. HARD

First-level cache is the Session/PersistenceContext: within one session, the same entity id is returned without re-querying. It is always on and cannot be disabled.

Second-level cache is shared across sessions. It is optional and disabled by default; use it for read-mostly entities. Hibernate ships providers such as EHCache. Queries are cached separately via the query cache. Overusing the second-level cache adds invalidation complexity - cache sparingly.

7 What is the difference between Hibernate and JPA? EASY

JPA is the Java specification (Jakarta Persistence) defining the API and mapping annotations. Hibernate is one implementation (the reference implementation) of that specification. You write against JPA interfaces (@Entity, EntityManager, @PersistenceContext) and can swap the provider; Hibernate adds extra features like second-level cache and native criteria.

8 What is an Entity in JPA and what rules must it follow? EASY

An entity is a plain Java class mapped to a database table. Rules: it must be annotated @Entity, have a no-arg constructor, a primary key (@Id), and its persistent fields map to columns. Entities should not be final, and field access must be either all fields or all getters (consistency).

9 What is the difference between save(), persist(), update() and merge() in Hibernate? MEDIUM
  • persist() - makes a transient instance persistent (INSERT); the object keeps its identity.
  • save() - similar to persist but returns the generated id; a legacy Hibernate method.
  • update() - re-attaches a detached instance (issues UPDATE).
  • merge() - copies state of a detached instance into a persisted instance and returns the managed copy; the passed object stays detached. Prefer merge() over update() in JPA code.
10 What are the four entity states in Hibernate? MEDIUM

Transient - new object, not associated with a session, no DB row. Persistent - associated with a session and tracked; changes are flushed to the DB. Detached - was persistent but the session closed; changes are not tracked. Removed - a delete is pending. The session/session context drives the transitions between these states.

11 What is the difference between get() and load() in Hibernate? MEDIUM

get() loads an entity immediately and returns null if the row does not exist. load() is lazy: it returns a proxy without hitting the DB, and throws ObjectNotFoundException if the entity does not exist when the proxy is accessed. Use load() when you only need the object as a reference for associations.

12 What are the different types of Primary keys in JPA? MEDIUM

@GeneratedValue(strategy = ...): IDENTITY lets the DB auto-increment; SEQUENCE uses a DB sequence (Hibernate default, efficient batching); TABLE emulates a sequence with a table; AUTO lets the provider choose. You may also assign keys manually, or use composite keys with @EmbeddedId/@IdClass.

13 What is the difference between @OneToMany and @ManyToOne and where is the owning side? MEDIUM

@ManyToOne is the many side (many rows reference one parent); @OneToMany is the inverse. The owning side of a bidirectional association is the one holding the foreign key - usually the @ManyToOne side. Updates are written from the owning side; the inverse uses mappedBy and is read-only for relationship management.

14 What is lazy loading and how does it fail with LazyInitializationException? HARD

Lazy loading defers loading of collections/associations until they are accessed, improving performance. The exception is thrown when a lazy property is accessed outside the session that loaded the entity - for example a collection read in a view after the transaction closed. Fixes: initialize within the transaction (fetch join), use Hibernate.initialize(), configure open-session-in-view carefully, or switch to DTOs.

15 What is N+1 query problem and how do you solve it? HARD

You issue one query for a list of parents, then, while iterating, Hibernate fires one extra query per child access - N+1 queries total. Solutions: join fetch or @EntityGraph to load associations in the main query, second-level cache, or batch fetching (@BatchSize).

16 What is an EntityManager and what is its relationship to the persistence context? EASY

EntityManager is the JPA interface for creating, reading, updating and deleting entities. The persistence context is a first-level set of managed entity instances that the EntityManager tracks; it acts as the first-level cache and delay-writes changes until flush/commit.

17 What is the difference between first-level and second-level cache? MEDIUM

First-level cache is the persistence context: per-session (or per-transaction), always on, prevents duplicate loads of the same id within a session. Second-level cache is a session-global (application-level) cache shared across sessions, configured per entity with @Cacheable and a provider such as EHCache; it caches entities and collections across sessions.

18 What is a Query Cache in Hibernate? HARD

The query cache stores the result set identifiers of executed queries (their entity ids and timestamps) so a repeated query can be answered without re-running the SQL. It only helps if the underlying entities/collections are in the second-level cache, and it must be explicitly enabled. Invalidated when related entities change.

19 What are the inheritance strategies in JPA? MEDIUM
  • SINGLE_TABLE - one table with a discriminator column; fastest but columns are nullable.
  • TABLE_PER_CLASS - one table per concrete class with all inherited columns duplicated; unions on query.
  • JOINED - one table per class plus a base table, joined on query; normalized but slow for deep hierarchies.
  • MAPPED_SUPERCLASS - not inheritance: shared fields are mapped into each child table, the parent is not an entity.
20 What is the difference between optional, required and element collections in mappings? HARD

Associations may be optional (nullable FK) or required (non-null FK), set with the nullable attribute of @JoinColumn. Element collections (@ElementCollection) store collections of basic or embeddable types (a List of Strings), which cannot be lazily fetched without careful config and are stored in a separate table. For entities prefer a real @OneToMany association instead.

21 How do you define a custom query in Spring Data JPA? MEDIUM

Use @Query with JPQL or native SQL on repository methods:

@Query("select u from User u where u.email = ?1")
Optional<User> findByEmailCustom(String email);

@Query(value = "select * from users where status='A'", nativeQuery = true)
List<User> findActive();

JPQL is portable; native queries are DB-specific but can use the full power of the dialect.

22 What is the difference between JPQL and native SQL in JPA? EASY

JPQL operates on entities and their fields, not tables: select u from User u where u.name = :name. It is database-agnostic. Native SQL is written in the actual database dialect against tables/columns; it enables DB-specific features but removes portability.

23 What is dirty checking in Hibernate? MEDIUM

When an entity is persistent, Hibernate snapshots its state at load time. At flush, it compares the current state with the snapshot and issues UPDATE statements only for changed entities - no explicit save is needed after modifying a managed object. Merge() can be used to re-attach detached modifications.

24 What is the difference between flush and commit? MEDIUM

flush() synchronizes the persistence context with the database - pending INSERT/UPDATE/DELETE statements are executed but the transaction is not finished. commit() ends the transaction, flushes first, then makes the changes durable. flush can be triggered automatically (AUTO mode) before queries that may be affected.

25 What is FlushMode and what are its values? HARD

FlushMode controls when the session flushes changes: AUTO (default - flush before queries that could be affected by pending changes), COMMIT (flush only at commit - risks stale query results), MANUAL/NEVER (flush only when you call flush() explicitly - best performance, but you must manage timing).

26 How do you enable batch inserts in Hibernate? MEDIUM

Set hibernate.jdbc.batch_size (e.g. 20-50) so multiple INSERT/UPDATE statements are grouped into batches sent in one round trip. With IDENTITY keys, batching is limited because the id must be known; use SEQUENCE keys and order inserts for best results.

hibernate.jdbc.batch_size=50
hibernate.order_inserts=true
hibernate.order_updates=true
27 What is the difference between optimistic and pessimistic locking? MEDIUM

Optimistic locking uses a version column (@Version): each UPDATE checks the version, and a concurrent write bumps it - the loser gets an OptimisticLockException. No locks during read; best for read-heavy apps. Pessimistic locking acquires DB locks (SELECT ... FOR UPDATE via LockMode) up front, guaranteeing no conflict but reducing concurrency.

28 What is a detached entity and how do you avoid detached state errors? MEDIUM

An entity becomes detached when its session closes (or after clear()). Attempting to reference or persist its lazy associations outside the session can throw LazyInitializationException, and re-saving it may create duplicates. Re-attach with merge() or update(), or fetch everything needed before the session ends.

29 What is the difference between cascade and orphanRemoval in JPA? MEDIUM

cascade propagates operations (PERSIST, REMOVE, MERGE, ALL) from parent to children - e.g. saving a parent also saves its children. orphanRemoval = true deletes an entity that has been removed from the collection, i.e. it is orphaned from its parent. They are independent: orphanRemoval only applies to relationships.

30 How do you convert between entities and DTOs and why? EASY

You map entity fields into plain DTO objects either manually, with MapStruct, or via JPQL constructor expressions. Benefits: you fetch only the columns you need (fewer round trips, less memory), decouple the API from the entity model, avoid lazy-loading and Jackson serialization issues (cycles, LazyInitializationException) and hide internal fields.