Skip to content

Commit

Permalink
[hibernate#751] VertxInstance service documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
DavideD committed Aug 9, 2021
1 parent 2d9db3c commit b5f6bc4
Showing 1 changed file with 100 additions and 0 deletions.
100 changes: 100 additions & 0 deletions documentation/src/main/asciidoc/reference/introduction.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ configuration based on Hibernate's `ServiceRegistry` architecture, by using a

=== Obtaining a reactive session

:vertx-context-introduction: https://vertx.io/blog/an-introduction-to-the-vert-x-context-object/

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.
Expand Down Expand Up @@ -637,6 +639,28 @@ session.find(Book.class, id)
.eventually(session::close);
----

It's also important that the session obtained via `openSession`
is used in the same Vert.x context it's been created or you might see the following exception:

[source, JAVA, indent=0]
----
HR000068: This method should exclusively be invoked from a Vert.x EventLoop thread; ...
----

One way to run the code in the correct {vertx-context-introduction}[Vert.x context] is the following:

[source, JAVA, indent=0]
----
Context currentContext = Vertx.currentContext();
currentContext.runOnContext( event -> {
// Here you will be able to use the session
});
----

Hibernate Reactive will create a default Vert.x instance when
needed. If your application has one already, you can register it via the
<<_vert_x_instance_service>>.

=== Using the reactive session

The `Session` interface has methods with the same names as methods of the JPA
Expand Down Expand Up @@ -891,6 +915,82 @@ sessionFactory.withTransaction( (session, tx) -> session.persist(book) )

This is probably the most convenient thing to use most of the time.

=== Vert.x instance service

:jdk-service-loader: https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html

The session is not thread-safe, using it in different threads may cause issues that are hard to debug.
Also, when a new session is created is bound to a Vert.x context and needs to be used in the same context after that.

Hibernate Reactive will take care of this when the application uses `withSession`
or `withTransaction` (See <<_obtaining_a_reactive_session>>).
For all the other cases, the `VertxInstance` service is available.

This service tells Hibernate Reactive which Vert.x instance to use when it
creates a session. It also acts as an integration point for your application
in case you need a custom Vert.x instance (Hibernate Reactive will create a
default one otherwise).

You can override the service programmatically:

[source, JAVA, indent=0]
----
Configuration configuration = new Configuration();
StandardServiceRegistryBuilder builder = new ReactiveServiceRegistryBuilder()
.addService( VertxInstance.class, (VertxInstance) () -> getMyVertxInstance() )
.applySettings( configuration.getProperties() );
StandardServiceRegistry registry = builder.build();
SessionFactory sessionFactory = configuration.buildSessionFactory( registry );
----

Or, you can define it using {jdk-service-loader}[the ServiceLoader mechanism of the JDK]:

1. Add a text file named `org.hibernate.reactive.vertx.VertxInstance` under
+
[source, JAVA, indent=0]
----
/META-INF/services/
----

2. The text file will contain the path to the class implementing the VertxInstance interface:
+
[source, JAVA, indent=0]
----
org.myproject.MyVertxProvider
----
+
This is an example what `MyVertxProvider` might took like:
+
[source, JAVA, indent=0]
----
public class MyVertxProvider implements VertxInstance {
private final Vertx vertx;
public MyVertxProvider(Vertx vertx) {
Objects.requireNonNull( vertx );
this.vertx = vertx;
}
@Override
public Vertx getVertx() {
return vertx;
}
}
----

The service is availabl via the `ServiceRegistry`:

[source, JAVA, indent=0]
----
org.hibernate.SessionFactory sessionFactory = ...
VertxInstance vertxInstance = sessionFactory
.unwrap( SessionFactoryImplementor.class )
.getServiceRegistry()
.getService( VertxInstance.class );
Vertx vertx = vertxInstance.getVertx();
----

== Tuning and performance

Once you have a program up and running using Hibernate Reactive to access
Expand Down

0 comments on commit b5f6bc4

Please sign in to comment.