Skip to main content

Hibernate Reactive

Hibernate Reactive 2.3.1.Final Reference Documentation

Hibernate Reactive is a reactive API for Hibernate ORM, supporting non-blocking database drivers and a reactive style of interaction with the database.

The reactive stream is represented using a chain of Java CompletionStages or Mutiny Unis and Multis.

Java persistence frameworks like JDBC, JPA and Hibernate ORM were designed to use blocking IO for interaction with the database, and are therefore not appropriate for use in a reactive environment. As far as we know, Hibernate Reactive is the first true ORM implementation designed to take advantage of non-blocking database clients. Out of the box, the Vert.x clients for PostgreSQL, MySQL, DB2, SQL Server, Oracle, and CockroachDB are supported, though the architecture is not limited to these drivers.

Introduction to Hibernate Reactive

Obtaining a reactive session factory

The first step to getting a reactive session is to obtain a JPA EntityManagerFactory:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("example");

Now, unwrap() the reactive SessionFactory. If you want to use CompletionStages for chaining reactive operations, ask for a Stage.SessionFactory:

CompletionStages

Stage.SessionFactory sessionFactory = emf.unwrap(Stage.SessionFactory.class);

If you prefer to use the Mutiny-based API, unwrap() the type Mutiny.SessionFactory:

Mutiny

Mutiny.SessionFactory sessionFactory = emf.unwrap(Mutiny.SessionFactory.class);

Obtaining a reactive session

Persistence operations are exposed via a reactive Session object.
It’s very important to understand that most operations of this interface are non-blocking, and execution of SQL against the database is never performed synchronously.
Persistence operations that belong to a single unit of work must be chained by composition within a single reactive stream.

To obtain a reactive Session from the SessionFactory, use withSession():

sessionFactory.withSession(
session -> session.find(Book.class, id)
.invoke(
book -> ... //do something with the book
)
);

The resulting Session object is automatically associated with the current reactive stream, and so nested calls to withSession() in a given stream automatically obtain the same shared session.

Alternatively, you may use openSession(), but you must remember to close() the session when you’re done. And you must take great care to only access each session from within exactly one Vert.x context. (See Sessions and Vert.x contexts more on this).

Uni<Session> sessionUni = sessionFactory.openSession();
sessionUni.chain(
session -> session.find(Book.class, id)
.invoke(
book -> ... //do something with the book
)
.eventually(session::close)
);

Example

http://jreact.com/index.php/2023/11/16/hibernate-reactive-completionstage-and-mutiny-example/