使用 Flyway 在 Quarkus 上进行反应式休眠

Reactive hibernate on Quarkus with Flyway

我在尝试将 Quarkus Flyway 扩展与 Quarkus Reactive Hibernate 和 RESTEasy 结合使用时遇到问题。启动我的应用程序时,出现以下错误:

[io.qu.ru.Application] (Quarkus Main Thread) Failed to start application (with profile dev): java.lang.IllegalStateException: Booting an Hibernate Reactive serviceregistry on a non-reactive RecordedState!
    at io.quarkus.hibernate.reactive.runtime.boot.registry.PreconfiguredReactiveServiceRegistryBuilder.checkIsReactive(PreconfiguredReactiveServiceRegistryBuilder.java:76)
    at io.quarkus.hibernate.reactive.runtime.boot.registry.PreconfiguredReactiveServiceRegistryBuilder.<init>(PreconfiguredReactiveServiceRegistryBuilder.java:66)
    at io.quarkus.hibernate.reactive.runtime.FastBootHibernateReactivePersistenceProvider.rewireMetadataAndExtractServiceRegistry(FastBootHibernateReactivePersistenceProvider.java:177)
    at io.quarkus.hibernate.reactive.runtime.FastBootHibernateReactivePersistenceProvider.getEntityManagerFactoryBuilderOrNull(FastBootHibernateReactivePersistenceProvider.java:156)
    at io.quarkus.hibernate.reactive.runtime.FastBootHibernateReactivePersistenceProvider.createEntityManagerFactory(FastBootHibernateReactivePersistenceProvider.java:82)

以下是相关的 Quarkus 配置:

quarkus:
  datasource:
    db-kind: "postgresql"
    username: "sarah"
    password: "connor"
    jdbc:
      ~: true
      url: "jdbc:postgresql://localhost:5432/mybase"
    reactive:
      ~: true
      url: "postgresql://localhost:5432/mybase"

及相关依赖:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-reactive-panache</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-flyway</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>

使用 ~: false 禁用 JDBC 配置可避免异常,但应用程序不会在启动时启动 Flyway 迁移。在这种情况下,我会看到以下消息:

[io.qu.ag.de.AgroalProcessor] (build-39) The Agroal dependency is present but no JDBC datasources have been defined.

我发现在一些 Quarkus 问题上,确实不可能同时 运行 反应式和阻塞式数据库连接,但是有没有办法让 Flyway 使用 反应式 Quarkus 应用程序?

目前他们似乎确实不支持同时阻塞 JDBC 和响应式 sql 客户端。 解决方法是在 Quarkus 运行 时间禁用 JDBC 并编写您自己的包装器来执行 Flyway 迁移。

以下解决方法基于它们对应的 GitHub issue.

当应用程序启动时 运行 的 Flyway 包装器:

@ApplicationScoped
public class RunFlyway {

    @ConfigProperty(name = "myapp.flyway.migrate")
    boolean runMigration;

    @ConfigProperty(name = "quarkus.datasource.reactive.url")
    String datasourceUrl;
    @ConfigProperty(name = "quarkus.datasource.username")
    String datasourceUsername;
    @ConfigProperty(name = "quarkus.datasource.password")
    String datasourcePassword;

    public void runFlywayMigration(@Observes StartupEvent event) {
        if (runMigration) {
            Flyway flyway = Flyway.configure().dataSource("jdbc:" + datasourceUrl, datasourceUsername, datasourcePassword).load();
            flyway.migrate();
        }
    }
}

pom.xml:

<!-- DB -->
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-reactive</artifactId>
</dependency>

<!-- Flyway -->
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-flyway</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>

application.yml:

myapp:
  flyway:
    migrate: true
quarkus:
  datasource:
    db-kind: postgresql
    username: myuser
    password: mypassword
    jdbc: false
    reactive:
      url: postgresql://localhost:5432/mydb