Getting Started with Hibernate

This section documents Hibernate ORM 7.4.x (User Guide, Introduction, Query Language Guide, Data Repositories Guide), Jakarta Persistence 3.2, Hibernate Search 8.4.x, and the Hibernate Validator / Hibernate Reactive references — which are the references these pages are written and verified against.

This content was generated with the assistance of AI and should be verified against those official docs before being relied on in production.

Three older reference books were consulted as bibliography only while preparing these pages and are not the primary or main source for any page. All three predate Jakarta Persistence 3.2 and Hibernate ORM 6/7 (the javax.persistencejakarta.persistence namespace change, the ORM 6 query-engine rewrite, the Hibernate Search 6+ Elasticsearch backend), so the official documentation above wins on any discrepancy.

This section’s bibliography lists the reference material consulted while preparing these pages.

This page gets a bare Hibernate ORM project running: what Hibernate is in relation to Jakarta Persistence, the Maven coordinates, the two ways to bootstrap it, and a minimal "Hello, Hibernate" example.

Hibernate and Jakarta Persistence

Jakarta Persistence (formerly JPA, Java Persistence API) is a specification: a set of interfaces and annotations (jakarta.persistence.) that describe object/relational mapping without prescribing an implementation. *Hibernate ORM is the reference, most widely used implementation of that specification — it also exposes a richer native API (org.hibernate.: SessionFactory, Session, StatelessSession) that goes beyond what the spec defines. Code written purely against jakarta.persistence. can, in principle, run against another provider (EclipseLink, OpenJPA); code that uses org.hibernate.* types is tied to Hibernate.

Jakarta Persistence 3.2 is the current specification version, aligned with Hibernate ORM 7.x. A prior, easy to trip over, historical detail: Java EE’s rebrand to Jakarta EE 9 moved every javax. namespace to jakarta., so javax.persistence.Entity became jakarta.persistence.Entity. Always use jakarta.persistence.* in new code — this section never uses the old javax.persistence package.

Adding Hibernate to a build

Maven, using the hibernate-platform BOM to pin compatible versions of Hibernate and its transitive dependencies:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-platform</artifactId>
            <version>7.4.0.Final</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.hibernate.orm</groupId>
        <artifactId>hibernate-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

Gradle equivalent: implementation platform("org.hibernate.orm:hibernate-platform:7.4.0.Final") plus implementation "org.hibernate.orm:hibernate-core". Under Spring Boot, none of this is needed directly — spring-boot-starter-data-jpa already brings in a compatible hibernate-core (see Hibernate (JPA & ORM)); this section documents plain Jakarta Persistence/Hibernate, with Spring Boot noted only where it changes something.

Bootstrapping: persistence.xml vs. programmatic

The standard, portable way to describe a persistence unit is META-INF/persistence.xml on the classpath:

<persistence xmlns="https://jakarta.ee/xml/ns/persistence" version="3.2">
    <persistence-unit name="library" transaction-type="RESOURCE_LOCAL">
        <class>com.example.library.Book</class>
        <properties>
            <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/library"/>
            <property name="jakarta.persistence.jdbc.user" value="library"/>
            <property name="jakarta.persistence.jdbc.password" value="library"/>
            <property name="hibernate.hbm2ddl.auto" value="validate"/>
        </properties>
    </persistence-unit>
</persistence>
EntityManagerFactory emf = Persistence.createEntityManagerFactory("library");

Hibernate also supports a fully programmatic bootstrap via org.hibernate.cfg.Configuration or the native bootstrap SPI (StandardServiceRegistryBuilder + MetadataSources), useful when settings come from code rather than a static file, or when embedding Hibernate in a framework that supplies its own DataSource — this is how Spring Boot builds the EntityManagerFactory bean without a persistence.xml at all.

"Hello, Hibernate"

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    protected Book() {
        // required no-arg constructor for Hibernate's proxying/reflection
    }

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

    // getters and setters omitted
}

public class HelloHibernate {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("library");
        try (EntityManager em = emf.createEntityManager()) {
            em.getTransaction().begin();
            em.persist(new Book("Hello, Hibernate"));
            em.getTransaction().commit();

            List<Book> books = em.createQuery("select b from Book b", Book.class).getResultList();
            books.forEach(b -> System.out.println(b.getTitle()));
        } finally {
            emf.close();
        }
    }
}

hibernate.properties and the most-used settings

An alternative to embedding properties in persistence.xml is a hibernate.properties file on the classpath, read automatically at bootstrap. The settings reached for most often:

Property Purpose

hibernate.hbm2ddl.auto

Schema-generation mode (none/validate/update/create/create-drop) — see Schema Generation & Tooling.

hibernate.show_sql / hibernate.format_sql / hibernate.highlight_sql

Log generated SQL to stdout, pretty-printed and syntax-highlighted — useful while learning, noisy in production (prefer a JDBC-driver-level or logger-based approach there).

hibernate.dialect

Usually auto-detected from the JDBC URL/driver since Hibernate 6; set explicitly only when detection is ambiguous.

hibernate.connection.provider_class / hibernate.hikari.*

Connection-pool selection and tuning when not letting a framework (Spring Boot) supply the DataSource.

hibernate.jdbc.batch_size

JDBC statement batching — see Bulk Operations & Batching.

Logging generated SQL through a real logger (rather than hibernate.show_sql) uses the org.hibernate.SQL (statement) and org.hibernate.orm.jdbc.bind (bound parameter values) logger categories.