quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.82k stars 2.69k forks source link

Hibernate reactive + Flyway extension causes UnsatisfiedResolutionException #10716

Closed burmanm closed 1 year ago

burmanm commented 4 years ago

Describe the bug Simply adding the quarkus-flyway extension when using Hibernate Reactive causes:

Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.persistence.EntityManagerFactory and qualifiers [@Default]
    - java member: io.quarkus.hibernate.reactive.runtime.ReactiveSessionFactoryProducer#emf
    - declared on CLASS bean [types=[io.quarkus.hibernate.reactive.runtime.ReactiveSessionFactoryProducer, java.lang.Object], qualifiers=[@Default, @Any], target=io.quarkus.hibernate.reactive.runtime.ReactiveSessionFactoryProducer]
    at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:487)
    at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:362)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:226)

Expected behavior Flyway should be usable in an application that uses the hibernate-reactive extension.

Actual behavior Will not start.

To Reproduce Steps to reproduce the behavior:

  1. Take hibernate-reactive-quickstart

  2. Add the following dependencies:

        <!-- Flyway specific dependencies -->
        <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-flyway</artifactId>
        </dependency>
    
        <!-- JDBC driver dependencies -->
        <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-jdbc-postgresql</artifactId>
        </dependency>
  3. mvn quarkus:dev

Environment (please complete the following information):

Additional context (Add any other context about the problem here.)

quarkusbot commented 4 years ago

/cc @aguibert, @gavinking, @Sanne /cc @gsmet, @Sanne

geoand commented 4 years ago

Interesting. Do you have a small reproducer showing this problem?

I assume if it's just adding as simple as adding quarkus-flyway to the hibernate-reactive quickstart we don't need one.

geoand commented 4 years ago

Actually, this doesn't seem like a bug to me... Flyway requires that a blocking driver be present and the Hibernate Reactive Quickstart doesn't use one.

burmanm commented 4 years ago

The reproducer is the quickstart steps. So its a design choice to limit Hibernate Reactive from using Flyway? Even if Hibernate Reactive doesn't use it, what prevents it from just ignoring that blocking one (and let just Flyway use it) ?

Kinda defeats the point of quarkus-flyway if it doesn't work with any async db extensions.

geoand commented 4 years ago

Kinda defeats the point of quarkus-flyway if it doesn't work with any async db extensions.

quarkus-flyway needs a blocking driver because Flyway needs a blocking driver - it's not a Quarkus limitation.

As for using quarkus-flyway along with hibernate-reactive, did you try adding a blocking driver and configuring the jdbc URL? The Hibernate-Reactive quickstart doesn't do that obviously since the blocking driver isn't needed.

burmanm commented 4 years ago

Yes, I had a working flyway installation in my own project. I tried adding hibernate-reactive to it but that started the issues, the quickstart modification was just a reproducer.

geoand commented 4 years ago

OK, but the way you mention to reproduce the issue doesn't surface that concern.

Let me try something else and get back to you

geoand commented 4 years ago

Okay, my bad. I see that just adding quarkus-flyway and quarkus-postgresql and configuring a JDBC URL does indeed exhibit the behavior you said.

So yeah, it's definitely an issue, quarkus-hibernate-reactive shouldn't be blocked from starting just by the presence of quarkus-flyway (quarkus-postgresql on it's own doesn't cause a problem).

geoand commented 4 years ago

@Sanne, @aguibert @gsmet this ultimately comes down to the fact that HibernateOrmProcessor.defineTypeOfImpliedPU defines a PU when quarkus-flyway is thrown into the mix (because it results in AgroalProcessor being run which is normally excluded by the hibernate-reactive extension). That leads to 2 PersistenceUnitDescriptorBuildItem being created and HibernateOrmProcessor not registering DefaultEntityManagerFactoryProducer as a bean as a result (in HibernateOrmProcessor.registerBeans).

So it seems to me that in order to fix this, we need some more clever way of interacting between the datasource configuration and hibernate extensions code.

gsmet commented 4 years ago

@Sanne @aguibert I think we should enable Hibernate Reactive if the Hibernate Reactive extension is around and a default reactive datasource is configured. I wouldn't take the presence of Agroal into consideration.

Sanne commented 4 years ago

@Sanne @aguibert I think we should enable Hibernate Reactive if the Hibernate Reactive extension is around and a default reactive datasource is configured. I wouldn't take the presence of Agroal into consideration.

I agree, that's what I had in mind to do. I suppose I got confused with things while working on the previous fix.

vhdirk commented 4 years ago

I can confirm this issue also exists for quarkus-liquibase. Is there a way to work around this for the time being?

gwenneg commented 3 years ago

@Sanne Is there a way to work around this issue until a fix is included into a Quarkus release?

gwenneg commented 3 years ago

By "this issue", I don't mean the ReactiveSessionFactoryProducer injection issue which can be easily worked around by duplicating the Quarkus producer. I'm more interested in the exception that comes after that:

2021-03-05 14:33:43,921 INFO  [org.fly.cor.int.lic.VersionPrinter] (Quarkus Main Thread) Flyway Community Edition 7.2.0 by Redgate
2021-03-05 14:33:43,973 INFO  [org.fly.cor.int.dat.bas.DatabaseType] (Quarkus Main Thread) Database: jdbc:postgresql://127.0.0.1:5432/notifications (PostgreSQL 13.2)
2021-03-05 14:33:43,993 INFO  [org.fly.cor.int.com.DbMigrate] (Quarkus Main Thread) Current version of schema "public": 1.9.0
2021-03-05 14:33:43,994 INFO  [org.fly.cor.int.com.DbMigrate] (Quarkus Main Thread) Schema "public" is up to date. No migration necessary.
2021-03-05 14:33:43,998 DEBUG [io.qua.hib.rea.run.FastBootHibernateReactivePersistenceProvider] (Quarkus Main Thread) Located 2 persistence units; checking each
2021-03-05 14:33:43,998 DEBUG [io.qua.hib.rea.run.FastBootHibernateReactivePersistenceProvider] (Quarkus Main Thread) Checking persistence-unit [name=default-reactive, explicit-provider=null] against incoming persistence unit name [default-reactive]
2021-03-05 14:33:44,002 INFO  [org.hib.rea.pro.imp.ReactiveIntegrator] (Quarkus Main Thread) HRX000001: Hibernate Reactive Preview
2021-03-05 14:33:44,014 DEBUG [io.qua.hib.rea.run.FastBootHibernateReactivePersistenceProvider] (Quarkus Main Thread) Located 2 persistence units; checking each
2021-03-05 14:33:44,014 DEBUG [io.qua.hib.rea.run.FastBootHibernateReactivePersistenceProvider] (Quarkus Main Thread) Checking persistence-unit [name=default-reactive, explicit-provider=null] against incoming persistence unit name [<default>]
2021-03-05 14:33:44,014 DEBUG [io.qua.hib.rea.run.FastBootHibernateReactivePersistenceProvider] (Quarkus Main Thread) Excluding from consideration 'default-reactive' due to name mis-match
2021-03-05 14:33:44,015 DEBUG [io.qua.hib.rea.run.FastBootHibernateReactivePersistenceProvider] (Quarkus Main Thread) Checking persistence-unit [name=<default>, explicit-provider=null] against incoming persistence unit name [<default>]
2021-03-05 14:33:44,017 INFO  [io.sma.rea.mes.provider] (Quarkus Main Thread) SRMSG00207: Cancel subscriptions
2021-03-05 14:33:44,017 ERROR [io.qua.run.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:164)
        at io.quarkus.hibernate.reactive.runtime.FastBootHibernateReactivePersistenceProvider.getEntityManagerFactoryBuilderOrNull(FastBootHibernateReactivePersistenceProvider.java:143)
        at io.quarkus.hibernate.reactive.runtime.FastBootHibernateReactivePersistenceProvider.createEntityManagerFactory(FastBootHibernateReactivePersistenceProvider.java:75)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:117)
        at io.quarkus.hibernate.orm.runtime.JPAConfig.startAll(JPAConfig.java:41)
        at io.quarkus.hibernate.orm.runtime.HibernateOrmRecorder.startAllPersistenceUnits(HibernateOrmRecorder.java:86)
        at io.quarkus.deployment.steps.HibernateOrmProcessor$startPersistenceUnits-2026547058.deploy_0(HibernateOrmProcessor$startPersistenceUnits-2026547058.zig:74)
        at io.quarkus.deployment.steps.HibernateOrmProcessor$startPersistenceUnits-2026547058.deploy(HibernateOrmProcessor$startPersistenceUnits-2026547058.zig:40)
        at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:971)
        at io.quarkus.runtime.Application.start(Application.java:90)
        at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:97)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:62)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:104)
        at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.runner.bootstrap.StartupActionImpl$3.run(StartupActionImpl.java:134)
        at java.base/java.lang.Thread.run(Thread.java:834)
Sanne commented 3 years ago

Hi @gwenneg , I'm not sure yet about a clever workaround - I need to have a better look, I'll start with this on Monday.

The core of the issue is that both ORM blocking and non-blocking are being triggered for initialization and there's a confusing mix of services being shared among them.

In terms of quick workarounds - would you be able to keep Flyway in a separate application? I've always wondered how far this belongs in the same deployment unit; for example it should be easy to have an app module which does take care of the migration, and a different app module which just boots on the migrated DB. It certainly would be more "minimal".

gwenneg commented 3 years ago

Thanks for your help on this one!

Keeping Flyway in a separate application could work indeed. I have a different kind of solution which seems to work fine in JVM mode (not so sure about native mode but I don't need it for now):

@ApplicationScoped
public class FlywayWorkaround {

    @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) {
        Flyway flyway = Flyway.configure().dataSource("jdbc:" + datasourceUrl, datasourceUsername, datasourcePassword).load();
        flyway.migrate();
    }
}

I wish I could keep quarkus-flyway in the project, but I need to focus on quarkus-hibernate-reactive for now so I'll probably stick with that workaround.

andreas-eberle commented 3 years ago

@gwenneg: How does your application.properties look like? I tried your code but I still get an error that the jdbc.url is not defined.

andreas-eberle commented 3 years ago

It looks to me that hibernate-reactive/reactive-postgres checks if the jdbc.url property is not configured on the datasource. At least it crashes as soon as that is the case. Why is this the case? Why shouldn't I be allowed to use the same datasource in a reactive and non-reactive way? The configuration could be the same for reactive and non-reactive and I could create different instances for each kind of driver.

gwenneg commented 3 years ago

@andreas-eberle My applications.properties file looks like this:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=removed
quarkus.datasource.password=removed
quarkus.datasource.jdbc=false
quarkus.datasource.reactive.url=postgresql://127.0.0.1:5432/mydb

The quarkus.datasource.jdbc=false line is very important. If it's missing, Quarkus won't boot.

andreas-eberle commented 3 years ago

@gwenneg. Thanks a lot!! We would have never thought of that!

Sanne commented 3 years ago

The reason is that in early days a datasource couldn't be both jdbc and reactive, and the Hibernate would look at what kind of datasource was configured to decide to boot as Hibernate ORM vs as Hibernate Reactive.

Until recently the integration of Hibernate Reactive was a POC taking advantage of some simplied assumptions; among these: if you're using Hibernate Reactive there won't be any blocking JDBC-based stuff. Clearly that's naive, but was considered acceptable as we focused on maturing the core of Hibernate Reactive.

Now that a single datasource can be both reactive and blocking, and we can have multiple datasource with different configurations, we need to correct the assumptions that the extension is making; we'll probably need some explicit way for users to choose what kind of Hibernate they want - however I'd love it if we could infer this automatically, provided it can be done in a robust and non-suprising way.

I'm open to suggestions :)

Same basic draft:

Currently the Hibernate Reactive extension depends on the blocking one, so if the Hibernate Reactive extension is missing it's easy: no hibernate reactive will start - but the opposite isn't true. I propose this is fine initially, we can refine the automatic guess in the future, as we could evolve the Hibernate Reactive extension to no longer depend on the blocking ORM extension.

More importantly, some other extensions use the JPA service while not using annotations to define injection points; for example if such other extension should perform programmatic lookup of EntityManager, this would fail. So we'll also need to introduce an SPI to allow other extensions to flag their actual need for a certain ORM instance to boot.

Interestingly it seems secutity-jpa uses the annotation explicitly, so that wouldn't need such an SPI - and I'm not aware of other modules needing this, so we might be able to implemet this in small steps.

andreas-eberle commented 3 years ago

I'd like to suggest to only have a single url property for datasources. As far as I understand, at the moment there is jdbc.url as well as reactive.url with the jdbc.url always starting with the addtional jdbc: prefix. I think it would be much cleaner to just have a single url property without the jdbc: prefix and add that prefix if JDBC is used and do not add it when reactive is used. This would reduce two properties which are mostly the same into one single one containing the required information.

famod commented 3 years ago

I can confirm this issue also exists for quarkus-liquibase.

FTR: #14682

markusdlugi commented 3 years ago

To add onto this, I think quarkus-quartz is also affected by this problem. Quartz requires quarkus-agroal, otherwise Quarkus won't boot, and if that dependency is present, Hibernate Reactive won't work anymore:

021-03-17 15:05:12,070 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
    [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.hibernate.reactive.mutiny.Mutiny$Session and qualifiers [@Default]
    - java member: com.example.FruitDao#session
    - declared on CLASS bean [types=[com.example.FruitDao, java.lang.Object], qualifiers=[@Default, @Any], target=com.example.FruitDao]
    at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1078)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:255)
    at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:129)
    at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:428)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:920)
    at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2415)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
    at java.base/java.lang.Thread.run(Thread.java:829)
    at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.hibernate.reactive.mutiny.Mutiny$Session and qualifiers [@Default]
    - java member: com.example.FruitDao#session
    - declared on CLASS bean [types=[com.example.FruitDao, java.lang.Object], qualifiers=[@Default, @Any], target=com.example.FruitDao]
    at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:484)
    at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:378)
    at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:247)
    ... 12 more
famod commented 3 years ago

@Sanne Thanks for those insights, really appreciated! I know you're a busy man, but how high is this on your priority list? 🙂 Seeing all those extensions not working with hibernate-reactive will most likely scare off potential users to actually even try hibernate-reactive in Quarkus. This is very much true for myself, currently starting a new not-so-small project based on Quarkus, with tight timelines - as ususal. :no_mouth:

Sanne commented 3 years ago

Yes this is fairly high on my priority list :) Breaking it down in multiple smaller tasks, and I'm getting some help.

theute commented 3 years ago

Hello ! Any update on this one ?

Sanne commented 3 years ago

Hi @theute , sorry this didn't make it yet, there's a significant amount of changes that need happening with the Hibernate Reactive integration first.

antoinechamot commented 3 years ago

Any update on this one ? This is really an annoying problem to work with Quarkus reactive

minhdtb1983 commented 3 years ago

@andreas-eberle My applications.properties file looks like this:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=removed
quarkus.datasource.password=removed
quarkus.datasource.jdbc=false
quarkus.datasource.reactive.url=postgresql://127.0.0.1:5432/mydb

The quarkus.datasource.jdbc=false line is very important. If it's missing, Quarkus won't boot.

not working with native build

2021-09-09 15:22:10,892 INFO [org.hib.rea.pro.imp.ReactiveIntegrator] (JPA Startup Thread: default-reactive) HR000001: Hibernate Reactive Preview 2021-09-09 15:22:10,896 ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): java.lang.IllegalStateException: 'org.flywaydb.core.internal.scanner.Scanner' is never used in Quarkus

marcozanghi commented 3 years ago

I am also facing with the following error when I try to inject Flyway in a @Singleton @Startup annotated class :

2021-11-14 20:56:41,902 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.flywaydb.core.Flyway and qualifiers [@Default]

My objective is to dinamically initialize multi tenant schemas ( at startup ) by loading the datasource from flyway instance. At the same time i want to use reactive model for serving REST and database access. The following is my application.property :


quarkus.hibernate-orm.database.generation=none
quarkus.hibernate-orm.multitenant=SCHEMA
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=
quarkus.datasource.password=
quarkus.datasource.jdbc=false
quarkus.datasource.reactive.url=postgresql://localhost:5432/db
quarkus.flyway.schemas=base,tenanta
quarkus.flyway.locations=classpath:db/migration
quarkus.flyway.migrate-at-start=false
EnvyIT commented 2 years ago

@Sanne Any progress on this issue? Feels pretty odd coming from Spring and experiencing such issues from the very beginning 😭

markusdlugi commented 2 years ago

@Sanne, @DavideD, @geoand

I wanted to bring up some additional points to further stress the importance of this issue. It's not just about Flyway, Quartz or whatever other extension might also depend on a JDBC datasource. These extensions not working when Hibernate Reactive is active is just a side-effect of a more severe problem in my opinion. The primary problem surfacing in this issue is that you currently don't have the possibility to run Hibernate ORM (i.e. Blocking) and Hibernate Reactive side-by-side.

However, running Blocking and Reactive next to each other is one of the main value propositions of Quarkus (or more specifically RESTeasy Reactive). It's even a feature that RESTeasy Reactive will automatically choose whether to run Blocking or Non-Blocking. At the same time, Hibernate Reactive officially doesn't support running on a worker thread, and will even print errors if you try to run it from anything other than an eventloop thread. You can try to work around those by disabling the HR assertions, but as mentioned, I guess it's not officially supported and the way it's intended to be used.

So that means that effectively, if you want to use Hibernate Reactive only for some parts of your application, that doesn't currently work - because HR doesn't support @Blocking while the issue at hand also prevents Hibernate ORM to work properly when HR is active. So in the end, at the moment it's kind of an all-or-nothing situation, where you either have to use HR for the entirety of your application or not at all. Which contradicts the previously mentioned value proposition of only using Reactive in some parts of your applications while sticking to Imperative in others.

I understand that you're busy with all kinds of stuff both in HR and ORM, and of course the work required to make this run smoothly is not trivial. But if you want people to actually use HR in anything more than sample applications, then this issue should really be prioritized.

Sorry for the long comment. I just wanted to share some of my experiences since we're actually running some applications with HR in production already, and while most of the time it's running smoothly, this issue has been bothering us for a long time now.

Sanne commented 2 years ago

Hi @markusdlugi , I don't disagree with you about this issue being important, and appreciate the honest feedback.

Still, I can't work on this now, and wouldn't suggest someone else to do so either: we're "full-steam" ahead in making Hibernate ORM v6 happen: when that's done this will unlock huge benefits for everyone, and will also require to make significant changes to the Hibernate Reactive code base and the Quarkus extensions, including the Envers exension, the Hibernate Search one, and all other 100+ Quarkus extensions depending on these.

To keep the overall workload somewhat achieavable with the small team, we need to execute in this particular order - I hope you appreciate that.

Not least to steer and guide the various teams into the right directions, some of us have POC and drafts exploring potential impact and need for changes in the integration areas, so starting a significant refactoring now in the extension structure of how the Hibernate ORM and Hibernate Reactive ones are related is bound to create huge conflicts - can't afford that.

I know it's not ideal, but I'm fine in conceding that Hibernate Reactive adoption can slow down a little - such needs of a more comprehensive integration are the reason for which it's still marked as experimental: great to have feedback from advanced users like you, but to achieve successfull mass adoption we need to execute on all these points, not just rush Flyway integration.

Until recently it didn't even have documentation nor support for Oracle; just a couple months ago it wasn't able to perform DDL operations... priorities :) Hopefully you're seeing the progress.

Thanks!

markusdlugi commented 2 years ago

Hi @Sanne, thanks a lot for taking the time to explain the situation, that definitely helps. Much appreciated!

cdmikechen commented 2 years ago

@andreas-eberle My applications.properties file looks like this:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=removed
quarkus.datasource.password=removed
quarkus.datasource.jdbc=false
quarkus.datasource.reactive.url=postgresql://127.0.0.1:5432/mydb

The quarkus.datasource.jdbc=false line is very important. If it's missing, Quarkus won't boot.

not working with native build

2021-09-09 15:22:10,892 INFO [org.hib.rea.pro.imp.ReactiveIntegrator] (JPA Startup Thread: default-reactive) HR000001: Hibernate Reactive Preview 2021-09-09 15:22:10,896 ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): java.lang.IllegalStateException: 'org.flywaydb.core.internal.scanner.Scanner' is never used in Quarkus

@minhdtb1983 You can change codes like this:

@ApplicationScoped
public class RunFlyway {

    private static final Logger LOGGER = Logger.getLogger(RunFlyway.class);

    @ConfigProperty(name = "quarkus.datasource.reactive.url")
    String datasourceUrl;
    @ConfigProperty(name = "quarkus.datasource.username")
    String datasourceUsername;
    @ConfigProperty(name = "quarkus.datasource.password")
    String datasourcePassword;
    // add a config to get files, we also need add `quarkus.native.resources.includes:db/migration/*.sql` to application.properties
    // example: db/migration/V1.0.1__InitDB.sql
    @ConfigProperty(name = "rds.flyway.native.files")
    List<String> files;

    public void runFlywayMigration(@Observes StartupEvent event) {
        LOGGER.info("int flyway ...");
        QuarkusPathLocationScanner.setApplicationMigrationFiles(files);
        DataSource ds = Flyway.configure().dataSource("jdbc:" + datasourceUrl, datasourceUsername, datasourcePassword).getDataSource();
        FlywayContainerProducer flywayProducer = Arc.container().instance(FlywayContainerProducer.class).get();
        FlywayContainer flywayContainer = flywayProducer.createFlyway(ds, "<default>", true, true);
        Flyway flyway = flywayContainer.getFlyway();
        flyway.migrate();
    }
}

I am considering reusing the existing code of io.quarkus.flyway to the greatest extent, using the data source built by flyway by default, and considering some processing of native mode.

seeseemelk commented 2 years ago

@cdmikechen I've tried this, but I keep getting the following error:

io.quarkus.runtime.configuration.ConfigurationException: Failed to load config value of type java.util.List<java.lang.String> for: rds.flyway.native.files

I can't find any documentation about such a configuration property. Is this something from your own application?

cdmikechen commented 2 years ago

@seeseemelk Yes, it is a custom config. I've written notes in codes.

Kasokaso commented 2 years ago

Is there any plan to implement this in the near future? I've tried this workaround solution and It seems it doesn't work for me. It seems there is an issue with Quartz as well ( in combination with reactive PostgreSQL url)

Build failed due to errors [error]: Build step io.quarkus.quartz.deployment.QuartzProcessor#driver threw an exception: io.quarkus.runtime.configuration.ConfigurationException: The Agroal extension is missing and it is required when a Quartz JDBC store is used.

euruba commented 2 years ago

Hi!, there are any update on this?

Thanks and regards

TheParad0X commented 2 years ago

Same problem here.

cdmikechen commented 2 years ago

Is there any plan to implement this in the near future? I've tried this workaround solution and It seems it doesn't work for me. It seems there is an issue with Quartz as well ( in combination with reactive PostgreSQL url)

Build failed due to errors [error]: Build step io.quarkus.quartz.deployment.QuartzProcessor#driver threw an exception: io.quarkus.runtime.configuration.ConfigurationException: The Agroal extension is missing and it is required when a Quartz JDBC store is used.

You can not use quartz with reactive postgresql, if you want to use it you must use jdbc.

cdmikechen commented 2 years ago

Hi!, there are any update on this?

Thanks and regards

This problem should not be solved in the short term, and flyway should not currently have plans to support reactive. My solution should only be a temporary solution.

TheParad0X commented 2 years ago

@seeseemelk Yes, it is a custom config. I've written notes in codes.

I dont' get it. How to you reference the migration files? 🤔

cdmikechen commented 2 years ago

@seeseemelk Yes, it is a custom config. I've written notes in codes.

I dont' get it. How to you reference the migration files? 🤔

I have explained in the code, you need to specify manually with a list.

seeseemelk commented 2 years ago

@seeseemelk Yes, it is a custom config. I've written notes in codes.

I dont' get it. How to you reference the migration files? 🤔

This is what I use in my application: https://gist.github.com/seeseemelk/27c601ad8ce5a6a89d423a476d6e9237

cdmikechen commented 2 years ago

@seeseemelk Yes, it is a custom config. I've written notes in codes.

I dont' get it. How to you reference the migration files? 🤔

This is what I use in my application: https://gist.github.com/seeseemelk/27c601ad8ce5a6a89d423a476d6e9237

Could you be sure that it will work under native as well?

TheParad0X commented 2 years ago

@seeseemelk Yes, it is a custom config. I've written notes in codes.

I dont' get it. How to you reference the migration files? 🤔

This is what I use in my application: https://gist.github.com/seeseemelk/27c601ad8ce5a6a89d423a476d6e9237

Can I see your application.properties? Do you have to list all migration files individually?

seeseemelk commented 2 years ago

Good point, I completely forgot about the application.properties. I believe it does work under native, but yes, one does need to list all migration files individually.

quarkus.datasource.db-kind=postgresql
quarkus.datasource.jdbc=false
quarkus.hibernate-orm.database.generation=none
quarkus.native.resources.includes=db/migration/*.sql
todo.migration.files=V1__initial.sql
y-luis-rojo commented 1 year ago

Hi. What's the state of this issue? We're evaluating the adoption of Quarkus in my company but this issue seems a key question: we have no way to avoid DB migrations and reactive seems one of the flagships of Quarkus. How is it suppose we could move on without giving-up on one? I am skeptic to go on with the workaround for a production ready product. At least, is there any timeline for this to be fixed?