diff --git a/docs/src/main/asciidoc/datasource.adoc b/docs/src/main/asciidoc/datasource.adoc index e4f0065489314..a56046cb64efd 100644 --- a/docs/src/main/asciidoc/datasource.adoc +++ b/docs/src/main/asciidoc/datasource.adoc @@ -177,6 +177,7 @@ Until now, the configuration has been the same regardless of whether you are usi When you have defined the database kind and the credentials, the rest depends on what type of driver you are using. It is possible to use JDBC and a reactive driver simultaneously. +[[jdbc-datasource]] ==== JDBC datasource JDBC is the most common database connection pattern, typically needed when used in combination with non-reactive Hibernate ORM. @@ -294,6 +295,7 @@ AgroalDataSource defaultDataSource; In the above example, the type is `AgroalDataSource`, a `javax.sql.DataSource` subtype. Because of this, you can also use `javax.sql.DataSource` as the injected type. +[[reactive-datasource]] ==== Reactive datasource Quarkus offers several reactive clients for use with a reactive datasource. @@ -325,10 +327,22 @@ Be aware that setting the pool size too low might cause some requests to time ou For more information about pool size adjustment properties, see the <> section. +[[jdbc-and-reactive-datasources-simultaneously]] ==== JDBC and reactive datasources simultaneously When a JDBC extension - along with Agroal - and a reactive datasource extension handling the given database kind are included, they will both be created by default. +If you want to use them both, +make sure to set both <> and <> configuration, +for example: + +[source,properties] +---- +%prod.quarkus.datasource.reactive.url=postgresql:///your_database +%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/hibernate_orm_test +---- + +If you do not want to have both a JDBC datasource and a reactive datasource created, use the following configuration. * To disable the JDBC datasource explicitly: + [source, properties] diff --git a/docs/src/main/asciidoc/flyway.adoc b/docs/src/main/asciidoc/flyway.adoc index 3544d4361e457..ecdee7ee18944 100644 --- a/docs/src/main/asciidoc/flyway.adoc +++ b/docs/src/main/asciidoc/flyway.adoc @@ -285,6 +285,23 @@ When using Flyway together with Hibernate ORM, you can use the Dev UI to generat You can find more information about this feature in the xref:hibernate-orm.adoc#flyway[Hibernate ORM guide]. +[[reactive-datasources]] +== Flyway and Reactive datasources + +Flyway internally relies on a JDBC datasource, +whereas reactive use cases will rely on xref:reactive-sql-clients.adoc[reactive SQL clients], +either directly or through xref:hibernate-reactive.adoc[Hibernate Reactive]. +This is not a problem in Quarkus, +because xref:datasource.adoc#jdbc-and-reactive-datasources-simultaneously[a single configured datasource can be made available both through reactive clients and JDBC]. + +To use Flyway on a datasource you otherwise access reactively, +simply make sure to configure that datasource +both as xref:datasource.adoc#jdbc-datasource[JDBC] +and xref:datasource.adoc#reactive-datasource[reactive]. +This involves in particular adding dependencies to Quarkus extensions +for both the JDBC driver and the reactive client, +for instance `quarkus-jdbc-postgresql` *and* `quarkus-reactive-pg-client`. + == Flyway on Kubernetes Sometimes, it's helpful not to execute Flyway initialization on each application startup. One such example is when deploying diff --git a/docs/src/main/asciidoc/hibernate-reactive.adoc b/docs/src/main/asciidoc/hibernate-reactive.adoc index 6a3efe3a2b594..52d2f412e0d66 100644 --- a/docs/src/main/asciidoc/hibernate-reactive.adoc +++ b/docs/src/main/asciidoc/hibernate-reactive.adoc @@ -224,6 +224,22 @@ This will inject the `Mutiny.SessionFactory` of the default persistence unit. NOTE: Prior to Quarkus 3.0 it was also possible to inject a `@RequestScoped` bean for `Mutiny.Session`. However, the lifecycle of a reactive session does not fit the lifecycle of the CDI request context. Therefore, this bean is removed in Quarkus 3.0. +[[flyway]] +== Automatically transitioning to Flyway to Manage Schemas + +Hibernate Reactive can be used in the same application as Flyway. +See xref:flyway.adoc#reactive-datasources[this section of the Flyway extension documentation] +for details regarding configuration of Flyway in a reactive application. + +[TIP] +==== +If you have the xref:flyway.adoc[Flyway extension] installed when running in development mode, +Quarkus provides a simple way to initialize your Flyway configuration +using the schema generated automatically by Hibernate Reactive. + +See xref:hibernate-orm.adoc#flyway[the Hibernate ORM guide] for more details. +==== + [[testing]] === Testing diff --git a/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/main/java/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLTestEndpoint.java b/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/main/java/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLTestEndpoint.java index bbf7070d9cf79..c068c7ef681b1 100644 --- a/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/main/java/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLTestEndpoint.java +++ b/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/main/java/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLTestEndpoint.java @@ -9,7 +9,6 @@ import org.hibernate.reactive.mutiny.Mutiny; import io.agroal.api.AgroalDataSource; -import io.quarkus.agroal.DataSource; import io.smallrye.mutiny.Uni; import io.vertx.mutiny.mysqlclient.MySQLPool; import io.vertx.mutiny.sqlclient.Row; @@ -28,15 +27,14 @@ public class HibernateReactiveMySQLTestEndpoint { MySQLPool mysqlPool; @Inject - @DataSource("blocking") - AgroalDataSource blockingDS; + AgroalDataSource jdbcDataSource; @GET - @Path("/blockingFind") - public GuineaPig blockingFind() throws SQLException { + @Path("/jdbcFind") + public GuineaPig jdbcFind() throws SQLException { final GuineaPig expectedPig = new GuineaPig(6, "Iola"); - populateDBBlocking(); - return selectBlocking(6); + populateDBJdbc(); + return selectJdbc(6); } @GET @@ -102,8 +100,8 @@ private Uni> populateDB() { .flatMap(junk -> mysqlPool.preparedQuery("INSERT INTO Pig (id, name) VALUES (5, 'Aloi')").execute()); } - private void populateDBBlocking() throws SQLException { - Connection connection = blockingDS.getConnection(); + private void populateDBJdbc() throws SQLException { + Connection connection = jdbcDataSource.getConnection(); connection.prepareStatement("DELETE FROM Pig").execute(); connection.prepareStatement("INSERT INTO Pig (id, name) VALUES (6, 'Iola')").execute(); connection.close(); @@ -121,8 +119,8 @@ private Uni selectNameFromId(Integer id) { }); } - private GuineaPig selectBlocking(Integer id) throws SQLException { - Connection connection = blockingDS.getConnection(); + private GuineaPig selectJdbc(Integer id) throws SQLException { + Connection connection = jdbcDataSource.getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT id, name FROM Pig WHERE id = ?"); statement.setInt(1, id); ResultSet rowSet = statement.executeQuery(); diff --git a/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/main/resources/application.properties b/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/main/resources/application.properties index d48dcb14b0856..227e44e7dda3f 100644 --- a/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/main/resources/application.properties +++ b/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/main/resources/application.properties @@ -1,16 +1,10 @@ -# Reactive datasource config +# Reactive+JDBC datasource config quarkus.datasource.db-kind=mysql quarkus.datasource.username=hibernate_orm_test quarkus.datasource.password=hibernate_orm_test quarkus.datasource.reactive.url=${reactive-mysql.url} - -# Blocking datasource config -quarkus.datasource.blocking.db-kind=mysql -quarkus.datasource.blocking.username=hibernate_orm_test -quarkus.datasource.blocking.password=hibernate_orm_test -quarkus.datasource.blocking.jdbc.url=${mysql.jdbc.url} -quarkus.datasource.blocking.jdbc=true -quarkus.datasource.blocking.jdbc.max-size=1 +quarkus.datasource.jdbc.url=${mysql.jdbc.url} +quarkus.datasource.jdbc.max-size=1 # Hibernate config #quarkus.hibernate-orm.log.sql=true @@ -18,4 +12,4 @@ quarkus.datasource.blocking.jdbc.max-size=1 quarkus.hibernate-orm.database.generation=none # Check that one can use Flyway alongside Hibernate Reactive -quarkus.flyway.blocking.migrate-at-start=true +quarkus.flyway.migrate-at-start=true diff --git a/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/test/java/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLTest.java b/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/test/java/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLTest.java index da83bb2d53c97..2bdff6cbd7022 100644 --- a/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/test/java/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLTest.java +++ b/integration-tests/hibernate-reactive-mysql-agroal-flyway/src/test/java/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLTest.java @@ -22,9 +22,9 @@ public void reactiveFindMutiny() { } @Test - public void blockingFind() { + public void jdbcFind() { RestAssured.when() - .get("/tests/blockingFind") + .get("/tests/jdbcFind") .then() .body(is("{\"id\":6,\"name\":\"Iola\"}")); }