Hibernate Basics


Hibernate Basics Interview with follow-up questions

1. What is Hibernate and why is it used?

Hibernate is an open-source Object-Relational Mapping (ORM) framework for Java. It maps Java objects (entities) to relational database tables, handling all the translation between the object model and the relational model automatically.

Why it is used:

  • Eliminates boilerplate JDBC code: No manual opening/closing of connections, ResultSet iteration, or PreparedStatement management.
  • Database portability: Switch databases by changing the dialect; SQL is generated by Hibernate rather than hand-coded.
  • Automatic dirty checking: Changes to managed entities are detected and flushed to the database at transaction commit — no explicit UPDATE calls needed.
  • Built-in caching: First-level cache (session scope) is always on; second-level cache (SessionFactory scope) is configurable with providers like Ehcache or Caffeine.
  • Lazy loading: Associations are fetched on demand, reducing unnecessary data retrieval.
  • JPA compliance: Hibernate is the leading implementation of the Jakarta Persistence API (JPA), so code written against JPA annotations (jakarta.persistence.*) is portable across JPA providers.

Current state (2025): Hibernate ORM 6.4.x is the current stable release, shipping with Spring Boot 3.x. It uses the jakarta.persistence package (not the legacy javax.persistence package) following the Jakarta EE 9+ migration.

Common follow-up: Interviewers often ask how Hibernate differs from plain JPA. JPA is the specification (interfaces and annotations); Hibernate is the most widely used implementation, adding features like @NaturalId, StatelessSession, and Criteria API extensions on top of the standard.

↑ Back to top

Follow-up 1

Can you explain the architecture of Hibernate?

The architecture of Hibernate is based on the following components:

  1. SessionFactory: It is a factory class that creates Session objects. It is thread-safe and should be instantiated only once during the application's lifetime.

  2. Session: It represents a single-threaded unit of work and provides methods for CRUD (Create, Read, Update, Delete) operations. It is not thread-safe and should be created and closed for each unit of work.

  3. Transaction: It represents a unit of work that is performed within a Session. It ensures the atomicity, consistency, isolation, and durability (ACID) properties of database transactions.

  4. Persistent Objects: These are the Java objects that are mapped to database tables using Hibernate annotations or XML mapping files. They represent the data stored in the database and can be manipulated using Hibernate APIs.

  5. Hibernate Configuration: It is a file (hibernate.cfg.xml) that contains the database connection details and other configuration settings for Hibernate.

Follow-up 2

What are the core interfaces of Hibernate?

The core interfaces of Hibernate are:

  1. SessionFactory: It is responsible for creating Session objects. It is typically created once during the application's startup and shared by all the threads.

  2. Session: It represents a single-threaded unit of work and provides methods for CRUD (Create, Read, Update, Delete) operations. It is obtained from the SessionFactory and should be closed after use.

  3. Transaction: It represents a database transaction and provides methods for managing transaction boundaries, such as begin(), commit(), and rollback(). It is obtained from the Session and should be used to wrap database operations.

  4. Query: It represents a database query and provides methods for executing queries and retrieving results. It is obtained from the Session and can be used to perform both HQL (Hibernate Query Language) and SQL queries.

  5. Criteria: It provides a type-safe and object-oriented way to build database queries using criteria queries. It is obtained from the Session and can be used as an alternative to HQL and SQL queries.

Follow-up 3

What are the benefits of using Hibernate?

Some of the benefits of using Hibernate are:

  1. Simplified Database Access: Hibernate eliminates the need for writing complex SQL queries and managing database connections manually. It provides a high-level object-oriented API for interacting with the database, making database access easier and more intuitive.

  2. Object-Relational Mapping: Hibernate maps Java objects to relational database tables and vice versa, allowing developers to work with objects instead of dealing with low-level JDBC code. This simplifies the development process and improves productivity.

  3. Database Independence: Hibernate provides a database abstraction layer that allows applications to be developed independent of the underlying database. It supports multiple databases, such as Oracle, MySQL, PostgreSQL, etc., without requiring any changes to the application code.

  4. Caching: Hibernate supports various levels of caching, such as first-level cache (session-level cache) and second-level cache (session factory-level cache). Caching improves application performance by reducing the number of database queries.

  5. Transaction Management: Hibernate provides built-in transaction management capabilities, ensuring the atomicity, consistency, isolation, and durability (ACID) properties of database transactions. It simplifies the management of database transactions and helps maintain data integrity.

  6. Lazy Loading: Hibernate supports lazy loading, which means that related objects are loaded from the database only when they are accessed. This improves performance by reducing the amount of data retrieved from the database.

  7. Integration with Java EE: Hibernate can be easily integrated with Java EE frameworks, such as Spring and JavaServer Faces (JSF), allowing developers to leverage the features and capabilities of these frameworks along with Hibernate.

2. What is the role of the Session interface in Hibernate?

The Session interface is the primary runtime interface between a Java application and Hibernate. It represents a single unit of work — typically scoped to one request or one business transaction — and acts as the first-level cache for that unit of work.

Key responsibilities:

  • CRUD operations: persist(), merge(), remove(), get(), load(), refresh().
  • Query execution: provides access to HQL/JPQL queries and the Criteria API.
  • First-level cache: every entity loaded within a Session is stored in its identity map; repeated lookups for the same ID return the cached instance without hitting the database.
  • Dirty checking: tracks state changes on managed entities and automatically generates SQL at flush time.
  • Transaction boundary: a Session is typically obtained, used within one transaction, then closed.

Session is Hibernate's native API. The JPA-standard equivalent is EntityManager. In modern Spring Boot 3.x / Hibernate 6 applications you will more commonly inject an EntityManager, but Session is still accessible via entityManager.unwrap(Session.class) when Hibernate-specific features are needed.

> Gotcha: Session is not thread-safe. Each thread must use its own Session instance.

↑ Back to top

Follow-up 1

How is a Session object obtained?

A Session object can be obtained using the SessionFactory. The SessionFactory is responsible for creating and managing Session objects. It can be created by calling the buildSessionFactory() method of the Configuration class.

Follow-up 2

What are some of the important methods of the Session interface?

Some of the important methods of the Session interface are:

  • save(Object entity): Saves the given entity to the database.
  • update(Object entity): Updates the given entity in the database.
  • delete(Object entity): Deletes the given entity from the database.
  • get(Class entityClass, Serializable id): Retrieves an entity from the database based on its class and identifier.
  • createQuery(String queryString): Creates a Query object for executing HQL (Hibernate Query Language) queries.

Follow-up 3

Can you explain the lifecycle of a Session?

The lifecycle of a Session in Hibernate can be summarized as follows:

  1. Opening: A Session is opened by calling the openSession() method of the SessionFactory.
  2. Persistence: Entities can be saved, updated, or deleted using the Session object.
  3. Flushing: Changes made to entities are synchronized with the database by calling the flush() method.
  4. Closing: A Session is closed by calling the close() method. Any changes made to entities after closing the Session will not be persisted.

3. What is the role of the Transaction interface in Hibernate?

The Transaction interface in Hibernate represents a database transaction scoped to a particular Session. It abstracts the underlying transaction mechanism — whether that is JDBC transactions, JTA (Java Transaction API), or a Spring-managed transaction.

Key methods:

  • begin() — starts the transaction.
  • commit() — persists all changes and ends the transaction.
  • rollback() — reverts all changes made in the transaction.
  • isActive() — checks whether the transaction is still open.

Transactions enforce ACID properties (Atomicity, Consistency, Isolation, Durability), ensuring that a series of database operations either all succeed or all fail together.

In practice (Spring Boot 3.x): explicit use of the Hibernate Transaction API is rare. Spring's @Transactional annotation manages transaction lifecycle declaratively, delegating to PlatformTransactionManager under the hood. Hibernate's Transaction object is still used internally, but developers typically never call begin() or commit() themselves.

> Gotcha: Always call rollback() in a finally block (or use try-with-resources patterns) when managing transactions manually to avoid leaving connections in a broken state.

↑ Back to top

Follow-up 1

What are some of the important methods of the Transaction interface?

The Transaction interface in Hibernate provides several methods for transaction management. Some of the important ones are:

  • begin(): This method starts a new transaction.

  • commit(): This method ends the transaction by committing the changes to the database.

  • rollback(): This method rolls back the transaction in case of any errors or exceptions, undoing all changes made in the transaction.

  • isActive(): This method checks if the transaction is still active.

  • wasCommitted(): This method checks if the transaction was successfully committed.

  • wasRolledBack(): This method checks if the transaction was rolled back.

Follow-up 2

Can you explain the lifecycle of a Transaction?

The lifecycle of a Transaction in Hibernate involves the following stages:

  1. Begin: A new transaction is started using the begin() method.

  2. Perform Operations: The desired operations (like save, update, delete) are performed on the entities.

  3. Commit or Rollback: If all operations are successful, the transaction is committed using the commit() method, and the changes are saved to the database. If any operation fails, the transaction is rolled back using the rollback() method, and all changes made in the transaction are undone.

  4. End: The transaction ends after it is either committed or rolled back.

Follow-up 3

How is a Transaction object obtained?

A Transaction object is obtained from the Session object in Hibernate. Here is a simple example:

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

In this example, sessionFactory is an instance of SessionFactory which is a factory for Session objects. openSession() is used to obtain a new Session object and beginTransaction() is used to start a new unit of work and return the associated Transaction object.

4. What is the role of the Configuration interface in Hibernate?

The Configuration class (in Hibernate native API) is the starting point for bootstrapping the Hibernate framework. It collects all the settings needed to create a SessionFactory:

  • Database connection properties (URL, driver, username, password).
  • Hibernate-specific settings (dialect, hbm2ddl.auto, show_sql, etc.).
  • Entity mappings — either annotated classes or hbm.xml mapping files.
// Hibernate 6 native bootstrap (standalone)
SessionFactory sessionFactory = new Configuration()
    .configure("hibernate.cfg.xml")
    .buildSessionFactory();

In modern Spring Boot 3.x applications the Configuration class is rarely used directly. Spring's auto-configuration reads application.properties (or application.yml) and constructs the EntityManagerFactory (the JPA-standard equivalent) automatically. Key properties:

spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=true

> Gotcha: Hibernate 6 deprecated many XML-based bootstrapping approaches. For new projects, prefer annotation-based entity scanning and Spring Boot auto-configuration over hibernate.cfg.xml.

↑ Back to top

Follow-up 1

How is a Configuration object obtained?

A Configuration object can be obtained by calling the new Configuration() constructor. Alternatively, you can use the Configuration.configure() method to obtain a Configuration object by loading the configuration from a specific file or resource.

Follow-up 2

What are some of the important methods of the Configuration interface?

Some of the important methods of the Configuration interface are:

  • configure(): Loads the configuration from a specific file or resource.
  • addAnnotatedClass(Class> annotatedClass): Adds an annotated entity class to the configuration.
  • setProperty(String propertyName, String value): Sets a specific property of the configuration.
  • buildSessionFactory(): Builds a SessionFactory based on the configuration.

Follow-up 3

Can you explain the lifecycle of a Configuration?

The lifecycle of a Configuration in Hibernate involves the following steps:

  1. Creation: A Configuration object is created using the new Configuration() constructor or by loading the configuration from a specific file or resource using the Configuration.configure() method.
  2. Configuration: The Configuration object is configured by adding annotated entity classes, setting properties, and specifying mapping files.
  3. SessionFactory creation: The buildSessionFactory() method is called to create a SessionFactory based on the configuration.
  4. SessionFactory usage: The SessionFactory is used to obtain Session objects for performing ORM operations.
  5. Shutdown: When the application is shutting down, the SessionFactory is closed using the SessionFactory.close() method.

5. What is the role of the ConnectionProvider interface in Hibernate?

ConnectionProvider is a Hibernate SPI (Service Provider Interface) that abstracts the source of JDBC connections. Hibernate calls it internally whenever it needs a connection; applications almost never implement it directly.

Hibernate ships with several built-in implementations:

Provider Usage
HikariCPConnectionProvider HikariCP pool — default in Spring Boot
C3P0ConnectionProvider C3P0 pool (legacy)
DatasourceConnectionProviderImpl delegates to a javax.sql.DataSource / jakarta. — used in managed environments
DriverManagerConnectionProvider one connection per request — development only

In Spring Boot 3.x, the connection pool is configured via the DataSource bean (HikariCP by default). Hibernate then receives the DataSource and wraps it with DatasourceConnectionProviderImpl. You configure the pool in application.properties:

spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.connection-timeout=30000

> Gotcha: For production workloads, always configure a proper connection pool. The DriverManagerConnectionProvider opens a new connection for every request and is not suitable for anything beyond local testing.

↑ Back to top

Follow-up 1

How is a ConnectionProvider object obtained?

A ConnectionProvider object can be obtained by configuring it in the Hibernate configuration file (hibernate.cfg.xml). The configuration file specifies the fully qualified class name of the ConnectionProvider implementation to be used. Hibernate then uses reflection to instantiate the ConnectionProvider object.

Follow-up 2

What are some of the important methods of the ConnectionProvider interface?

Some of the important methods of the ConnectionProvider interface are:

  • getConnection(): This method is used to obtain a database connection.
  • closeConnection(): This method is used to release a database connection.
  • configure(Properties props): This method is used to configure the ConnectionProvider with the given properties.
  • close(): This method is used to release any resources held by the ConnectionProvider.

Follow-up 3

Can you explain the lifecycle of a ConnectionProvider?

The lifecycle of a ConnectionProvider in Hibernate typically involves the following steps:

  1. Instantiation: The ConnectionProvider object is instantiated either through configuration or programmatically.
  2. Configuration: The ConnectionProvider is configured with the necessary properties, such as database URL, username, and password.
  3. Initialization: The ConnectionProvider is initialized, which may involve establishing a connection pool or other setup tasks.
  4. Connection retrieval: When Hibernate needs a database connection, it calls the getConnection() method of the ConnectionProvider.
  5. Connection release: After the database operation is complete, Hibernate calls the closeConnection() method of the ConnectionProvider to release the connection.
  6. Cleanup: When Hibernate is shutting down, it calls the close() method of the ConnectionProvider to release any resources held by it.

6. What is the difference between javax.persistence and jakarta.persistence, and why does it matter?

This is the single most important namespace change in the Java persistence ecosystem in recent years.

Background:

  • Prior to Jakarta EE 9 (2020), the JPA specification was maintained under the javax.persistence package as part of Java EE.
  • When Oracle transferred Java EE to the Eclipse Foundation, the project was renamed Jakarta EE. Due to trademark restrictions, the javax.* namespace could not be carried forward.
  • Starting with Jakarta EE 9, all former javax.persistence.* classes and annotations were moved to jakarta.persistence.*.

Practical impact:

Legacy (pre-Jakarta EE 9) Current (Jakarta EE 9+)
JPA package javax.persistence jakarta.persistence
Hibernate version Hibernate 5.x and earlier Hibernate 6.x
Spring Boot version Spring Boot 2.x Spring Boot 3.x

What changed (examples):

// OLD (Hibernate 5 / Spring Boot 2 — do NOT use in new code)
import javax.persistence.Entity;
import javax.persistence.Id;

// CURRENT (Hibernate 6 / Spring Boot 3)
import jakarta.persistence.Entity;
import jakarta.persistence.Id;

Migration gotcha: If you upgrade a project from Spring Boot 2 to Spring Boot 3, you must do a global find-and-replace of javax.persistencejakarta.persistence across all entity and repository classes. The code will not compile otherwise.

Interview tip: Any answer that references javax.persistence in the context of Hibernate 6 or Spring Boot 3 is incorrect. Interviewers at companies on modern stacks specifically probe this.

↑ Back to top

Live mock interview

Mock interview: Hibernate Basics

Intermediate ~5 min Your own free AI key

Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.