What Is Hibernate ORM?

When you use JDBC to read a row from a database, you normally write a SQL query, execute it, and copy the values from the ResultSet into a Java object. If your application has classes such as Book, Author, and Publisher, you repeat this kind of mapping for each class.

Hibernate ORM is a Java framework that handles much of this mapping. You describe how your Java classes correspond to tables, and Hibernate uses that information to load objects and save changes. This series uses Java 25 and Hibernate ORM 7.4.15.Final, the latest stable release as of November 9, 2026. Hibernate ORM 7.4 implements Jakarta Persistence 3.2. See the Hibernate ORM release notes.

What does ORM mean?

ORM stands for object-relational mapping. It connects the way Java represents data as objects with the way a relational database stores data in tables.

For a simple book catalog, the mapping looks like this.

Java Database
Book class books table
One Book object One row in books
id field id primary key column
title field title column

A class that Hibernate can persist is called an entity. Here is the first entity in our catalog.

package org.kodejava.hibernate;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "books")
public class Book {
    @Id
    private Long id;

    @Column(nullable = false)
    private String title;

    protected Book() {
    }

    public Book(Long id, String title) {
        this.id = id;
        this.title = title;
    }

    public String getTitle() {
        return title;
    }
}
  • @Entity marks Book as a persistent entity.
  • @Table(name = "books") maps the entity to the books table.
  • @Id identifies the field that maps to the primary key. This example assigns the ID in the constructor.
  • @Column(nullable = false) declares the title column as non-nullable in the mapping.

Hibernate can read and write the mapped fields directly because the mapping annotations are on the fields. The protected no-argument constructor allows the persistence provider to instantiate a Book when it loads data.

How does Hibernate save an object?

After Hibernate is configured, you can use an EntityManager to work with entities. The following snippet assumes an existing EntityManager and an active transaction.

Book book = new Book(1L, "Effective Java");
entityManager.persist(book);

Calling persist() makes the new Book a managed entity. Hibernate now tracks it in the persistence context. When Hibernate flushes the context, typically as part of committing the transaction, it executes an SQL statement similar to this one.

insert into books (title, id) values (?, ?)

Hibernate binds the values from the object to those parameters and executes the statement through JDBC. You can load a book by its primary key with entityManager.find(Book.class, 1L). If the persistence context already manages that book, Hibernate can return it directly. Otherwise, Hibernate can load it from the database, and find() returns null if the book does not exist.

What is the difference between Jakarta Persistence and Hibernate?

Jakarta Persistence, often called JPA, defines standard annotations and interfaces such as @Entity, @Id, and EntityManager. Hibernate ORM implements that standard and provides its own API, including SessionFactory and Session.

We will start with Jakarta Persistence so you can learn the standard mapping and transaction APIs. Later articles will use Hibernate-specific features where they help solve a concrete problem, such as inspecting SQL activity or tuning fetch behavior. The Hibernate ORM Javadocs describe both APIs.

Where does JDBC fit?

Hibernate uses JDBC to communicate with the database. With plain JDBC, you usually write the SQL and map the results yourself. With Hibernate, you provide entity mappings, and Hibernate handles many routine operations, such as inserting a row or finding it by primary key.

The SQL still matters. Loading a list of books and then accessing each book’s author can trigger extra queries. Later in the series, we will inspect the generated SQL and see how a fetch join can avoid that pattern.

In the next article, we will create a Maven project, configure an in-memory H2 database, and run the Book example from start to finish. We will use plain Java to make the Hibernate configuration and transaction boundaries visible.

Maven Dependencies

Add the following dependency inside the <dependencies> section of your pom.xml. Hibernate Core brings in the Jakarta Persistence API transitively, including the annotations used above. To run the example against a database, you will also need a JDBC driver. We will add the H2 driver in the next article.

<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>7.4.15.Final</version>
</dependency>