Skip to content

Conversation

marko-bekhta
Copy link
Contributor

fixes #34547

As we discussed in the linked issue, the order in which beans are destroyed is not guaranteed. With this patch, JPAConfig will observe the shutdown event and clean up the resources then.
Since persistent units are now going to be closed prior to datasource being destroyed this should allow Hibernate Search to stop things cleanly.

For the observer priority I've initially used the ObserverMethod.DEFAULT_PRIORITY as the base value but then noticed that it uses the one from the jakarta.interceptor.Interceptor.Priority and thought that:

Start of range for late interceptors defined by extension libraries.

might be the one applicable here 😃

@quarkus-bot quarkus-bot bot added area/hibernate-orm Hibernate ORM area/hibernate-search Hibernate Search labels Jan 8, 2025
Copy link

quarkus-bot bot commented Jan 8, 2025

/cc @gsmet (hibernate-orm,hibernate-search), @yrodiere (hibernate-orm,hibernate-search)

This comment has been minimized.

Copy link

github-actions bot commented Jan 8, 2025

🎊 PR Preview fecf60a has been successfully built and deployed to https://quarkus-pr-main-45451-preview.surge.sh/version/main/guides/

  • Images of blog posts older than 3 months are not available.
  • Newsletters older than 3 months are not available.

@gsmet gsmet requested review from mkouba and yrodiere January 8, 2025 17:05

This comment has been minimized.

@mkouba mkouba requested a review from manovotn January 9, 2025 11:43
Copy link
Contributor

@mkouba mkouba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

Copy link
Member

@yrodiere yrodiere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach looks good, though I have a few questions about the details...

Comment on lines -150 to -151
// but that would force initialization of JPAConfig upon application shutdown,
// which may cause cascading failures if the shutdown happened before JPAConfig was initialized.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... what about this? :)

I.e. if something fails while starting datasources (invalid credentials, ...), will we now see Quarkus attempt to start JPA just to shut it down, with stacktraces being appended after the real problem (datasource credentials)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙈🙈🙈😃
I've tried running a test with an incorrect password and with/without these injection points. Both result in the same log:

2025-02-07 09:18:23,091 WARN  [io.qua.run.log.LoggingSetupRecorder] (build-49) Log level TRACE for category 'io.quarkus.hibernate.orm.runtime' set below minimum logging level DEBUG, promoting it to DEBUG. Set the build time configuration property 'quarkus.log.category."io.quarkus.hibernate.orm.runtime".min-level' to 'TRACE' to avoid this warning
2025-02-07 09:18:24,129 DEBUG [io.qua.hib.orm.run.ser.FlatClassLoaderService] (main) HHH000194: Package not found or no package-info.java: io.quarkus.it.jpa.postgresql.defaultpu
2025-02-07 09:18:24,136 DEBUG [io.qua.hib.orm.run.ser.FlatClassLoaderService] (main) HHH000194: Package not found or no package-info.java: io.quarkus.it.jpa.postgresql.defaultpu
2025-02-07 09:18:24,138 DEBUG [io.qua.hib.orm.run.ser.FlatClassLoaderService] (main) HHH000194: Package not found or no package-info.java: io.quarkus.it.jpa.postgresql.defaultpu
2025-02-07 09:18:24,140 DEBUG [io.qua.hib.orm.run.ser.FlatClassLoaderService] (main) HHH000194: Package not found or no package-info.java: io.quarkus.it.jpa.postgresql.defaultpu
2025-02-07 09:18:24,142 DEBUG [io.qua.hib.orm.run.ser.FlatClassLoaderService] (main) HHH000194: Package not found or no package-info.java: io.quarkus.it.jpa.postgresql.defaultpu
2025-02-07 09:18:24,171 DEBUG [io.qua.hib.orm.run.ser.FlatClassLoaderService] (main) HHH000194: Package not found or no package-info.java: io.quarkus.it.jpa.postgresql.otherpu
2025-02-07 09:18:24,303 WARN  [io.qua.run.log.LoggingSetupRecorder] (main) Log level TRACE for category 'io.quarkus.hibernate.orm.runtime' set below minimum logging level DEBUG, promoting it to DEBUG. Set the build time configuration property 'quarkus.log.category."io.quarkus.hibernate.orm.runtime".min-level' to 'TRACE' to avoid this warning
2025-02-07 09:18:24,307 DEBUG [io.qua.hib.orm.run.FastBootHibernatePersistenceProvider] (JPA Startup Thread: other) Located 2 persistence units; checking each
2025-02-07 09:18:24,307 DEBUG [io.qua.hib.orm.run.FastBootHibernatePersistenceProvider] (JPA Startup Thread: <default>) Located 2 persistence units; checking each
2025-02-07 09:18:24,307 DEBUG [io.qua.hib.orm.run.FastBootHibernatePersistenceProvider] (JPA Startup Thread: other) Checking persistence-unit [name=<default>, explicit-provider=null] against incoming persistence unit name [other]
2025-02-07 09:18:24,307 DEBUG [io.qua.hib.orm.run.FastBootHibernatePersistenceProvider] (JPA Startup Thread: <default>) Checking persistence-unit [name=<default>, explicit-provider=null] against incoming persistence unit name [<default>]
2025-02-07 09:18:24,307 DEBUG [io.qua.hib.orm.run.FastBootHibernatePersistenceProvider] (JPA Startup Thread: other) Excluding from consideration '<default>' due to name mismatch
2025-02-07 09:18:24,307 DEBUG [io.qua.hib.orm.run.FastBootHibernatePersistenceProvider] (JPA Startup Thread: other) Checking persistence-unit [name=other, explicit-provider=null] against incoming persistence unit name [other]
2025-02-07 09:18:24,307 DEBUG [io.qua.hib.orm.run.FastBootHibernatePersistenceProvider] (JPA Startup Thread: <default>) No PersistenceProvider explicitly requested, assuming Hibernate
2025-02-07 09:18:24,307 DEBUG [io.qua.hib.orm.run.FastBootHibernatePersistenceProvider] (JPA Startup Thread: other) No PersistenceProvider explicitly requested, assuming Hibernate
2025-02-07 09:18:24,409 WARN  [io.agr.pool] (agroal-11) Datasource '<default>': FATAL: password authentication failed for user "hibernate_orm_test"
2025-02-07 09:18:24,409 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: other) SQL Error: 0, SQLState: 28P01
2025-02-07 09:18:24,409 ERROR [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: other) FATAL: password authentication failed for user "hibernate_orm_test"
2025-02-07 09:18:24,410 WARN  [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: other) HHH000342: Could not obtain connection to query metadata: org.hibernate.exception.GenericJDBCException: unable to obtain isolated JDBC connection [FATAL: password authentication failed for user "hibernate_orm_test"] [n/a]
	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:63)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:94)
	at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWork(JtaIsolationDelegate.java:206)
	at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.lambda$delegateWork$3(JtaIsolationDelegate.java:91)
	at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doInSuspendedTransaction(JtaIsolationDelegate.java:125)
	at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.delegateWork(JtaIsolationDelegate.java:88)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:320)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:129)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:81)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
	at org.hibernate.service.ServiceRegistry.requireService(ServiceRegistry.java:68)
	at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:52)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:136)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:247)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
	at org.hibernate.service.ServiceRegistry.requireService(ServiceRegistry.java:68)
	at org.hibernate.boot.internal.SessionFactoryOptionsBuilder.<init>(SessionFactoryOptionsBuilder.java:290)
	at io.quarkus.hibernate.orm.runtime.recording.PrevalidatedQuarkusMetadata.buildSessionFactoryOptionsBuilder(PrevalidatedQuarkusMetadata.java:72)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:84)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:72)
	at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
	at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:160)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:61)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: org.postgresql.util.PSQLException: FATAL: password authentication failed for user "hibernate_orm_test"
	at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:704)
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:213)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:268)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:273)
	at org.postgresql.Driver.makeConnection(Driver.java:446)
	at org.postgresql.Driver.connect(Driver.java:298)
	at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:225)
	at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:580)
	at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:561)
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
	at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:75)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	... 1 more

2025-02-07 09:18:24,415 WARN  [io.agr.pool] (agroal-11) Datasource '<default>': FATAL: password authentication failed for user "hibernate_orm_test"
2025-02-07 09:18:24,415 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: <default>) SQL Error: 0, SQLState: 28P01
2025-02-07 09:18:24,416 ERROR [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: <default>) FATAL: password authentication failed for user "hibernate_orm_test"
2025-02-07 09:18:24,416 WARN  [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: <default>) HHH000342: Could not obtain connection to query metadata: org.hibernate.exception.GenericJDBCException: unable to obtain isolated JDBC connection [FATAL: password authentication failed for user "hibernate_orm_test"] [n/a]
	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:63)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:94)
	at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doTheWork(JtaIsolationDelegate.java:206)
	at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.lambda$delegateWork$3(JtaIsolationDelegate.java:91)
	at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.doInSuspendedTransaction(JtaIsolationDelegate.java:125)
	at org.hibernate.resource.transaction.backend.jta.internal.JtaIsolationDelegate.delegateWork(JtaIsolationDelegate.java:88)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:320)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:129)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:81)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
	at org.hibernate.service.ServiceRegistry.requireService(ServiceRegistry.java:68)
	at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:52)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:136)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:247)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
	at org.hibernate.service.ServiceRegistry.requireService(ServiceRegistry.java:68)
	at org.hibernate.boot.internal.SessionFactoryOptionsBuilder.<init>(SessionFactoryOptionsBuilder.java:290)
	at io.quarkus.hibernate.orm.runtime.recording.PrevalidatedQuarkusMetadata.buildSessionFactoryOptionsBuilder(PrevalidatedQuarkusMetadata.java:72)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:84)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:72)
	at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
	at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:160)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:61)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: org.postgresql.util.PSQLException: FATAL: password authentication failed for user "hibernate_orm_test"
	at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:704)
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:213)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:268)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:273)
	at org.postgresql.Driver.makeConnection(Driver.java:446)
	at org.postgresql.Driver.connect(Driver.java:298)
	at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:225)
	at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:580)
	at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:561)
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
	at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:75)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	... 1 more

2025-02-07 09:18:24,636 WARN  [io.agr.pool] (agroal-11) Datasource '<default>': FATAL: password authentication failed for user "hibernate_orm_test"
2025-02-07 09:18:24,636 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: other) SQL Error: 0, SQLState: 28P01
2025-02-07 09:18:24,636 ERROR [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: other) FATAL: password authentication failed for user "hibernate_orm_test"

java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus

	at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:611)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:695)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.RuntimeException: Failed to start quarkus
	at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at io.quarkus.runner.bootstrap.StartupActionImpl.run(StartupActionImpl.java:305)
	at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:224)
	at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:578)
	at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:628)
	... 1 more
Caused by: jakarta.persistence.PersistenceException: [PersistenceUnit: other] Unable to build Hibernate SessionFactory
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.persistenceException(FastBootEntityManagerFactoryBuilder.java:129)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:89)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:72)
	at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
	at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:160)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:61)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution [FATAL: password authentication failed for user "hibernate_orm_test"] [n/a]
	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:63)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:94)
	at org.hibernate.resource.transaction.backend.jta.internal.DdlTransactionIsolatorJtaImpl.getIsolatedConnection(DdlTransactionIsolatorJtaImpl.java:77)
	at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.getIsolatedConnection(GenerationTargetToDatabase.java:60)
	at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.jdbcStatement(GenerationTargetToDatabase.java:112)
	at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:79)
	at org.hibernate.tool.schema.internal.Helper.applySqlString(Helper.java:233)
	at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:213)
	at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:186)
	at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:156)
	at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:116)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:238)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:144)
	at java.base/java.util.HashMap.forEach(HashMap.java:1421)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:141)
	at io.quarkus.hibernate.orm.runtime.observers.SessionFactoryObserverForSchemaExport.sessionFactoryCreated(SessionFactoryObserverForSchemaExport.java:21)
	at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:324)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:87)
	... 6 more
Caused by: org.postgresql.util.PSQLException: FATAL: password authentication failed for user "hibernate_orm_test"
	at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:704)
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:213)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:268)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:273)
	at org.postgresql.Driver.makeConnection(Driver.java:446)
	at org.postgresql.Driver.connect(Driver.java:298)
	at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:225)
	at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:580)
	at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:561)
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
	at --- Async.Stack.Trace --- (captured by IntelliJ IDEA debugger)
	at java.base/java.util.concurrent.FutureTask.<init>(FutureTask.java:132)
	at io.agroal.pool.util.PriorityScheduledExecutor.executeNow(PriorityScheduledExecutor.java:51)
	at io.agroal.pool.ConnectionPool.handlerFromSharedCache(ConnectionPool.java:329)
	at io.agroal.pool.ConnectionPool.getConnection(ConnectionPool.java:288)
	at io.agroal.pool.DataSource.getConnection(DataSource.java:86)
	at io.quarkus.hibernate.orm.runtime.customized.QuarkusConnectionProvider.getConnection(QuarkusConnectionProvider.java:23)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:467)
	at org.hibernate.resource.transaction.backend.jta.internal.DdlTransactionIsolatorJtaImpl.getIsolatedConnection(DdlTransactionIsolatorJtaImpl.java:74)
	... 22 more

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, but then I was wrong about credentials, since it obviously didn't make the datasource startup fail.

Maybe a JDBc URL with an invalid syntax?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I've tried a bad URL (some random text), using postgres url with oracle driver (Driver does not support the provided URL), no DB running -- same results as above 😕
if I try to use some random string for db-kind, things fail at build time without getting to the Hibernate ORM stuff:

java.lang.RuntimeException: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step io.quarkus.agroal.deployment.AgroalProcessor#build threw an exception: io.quarkus.runtime.configuration.ConfigurationException: Unable to find a JDBC driver corresponding to the database kind 'oracleaa' for the default datasource (available: 'oracle','postgresql'). Check if it's a typo, otherwise provide a suitable JDBC driver extension, define the driver manually, or disable the JDBC datasource by adding 'quarkus.datasource.jdbc=false' to your configuration if you don't need it.
	at io.quarkus.agroal.deployment.AgroalProcessor.resolveDriver(AgroalProcessor.java:358)
	at io.quarkus.agroal.deployment.AgroalProcessor.getAggregatedConfigBuildItems(AgroalProcessor.java:332)
	at io.quarkus.agroal.deployment.AgroalProcessor.build(AgroalProcessor.java:103)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:856)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:255)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
	at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
	at java.base/java.lang.Thread.run(Thread.java:840)
	at org.jboss.threads.JBossThread.run(JBossThread.java:499)


	at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:611)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:706)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step io.quarkus.agroal.deployment.AgroalProcessor#build threw an exception: io.quarkus.runtime.configuration.ConfigurationException: Unable to find a JDBC driver corresponding to the database kind 'oracleaa' for the default datasource (available: 'oracle','postgresql'). Check if it's a typo, otherwise provide a suitable JDBC driver extension, define the driver manually, or disable the JDBC datasource by adding 'quarkus.datasource.jdbc=false' to your configuration if you don't need it.
	at io.quarkus.agroal.deployment.AgroalProcessor.resolveDriver(AgroalProcessor.java:358)
	at io.quarkus.agroal.deployment.AgroalProcessor.getAggregatedConfigBuildItems(AgroalProcessor.java:332)
	at io.quarkus.agroal.deployment.AgroalProcessor.build(AgroalProcessor.java:103)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:856)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:255)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
	at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
	at java.base/java.lang.Thread.run(Thread.java:840)
	at org.jboss.threads.JBossThread.run(JBossThread.java:499)

	at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:354)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:271)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.createInitialRuntimeApplication(AugmentActionImpl.java:61)
	at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:195)
	at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:578)
	at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:628)
	... 1 more
Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step io.quarkus.agroal.deployment.AgroalProcessor#build threw an exception: io.quarkus.runtime.configuration.ConfigurationException: Unable to find a JDBC driver corresponding to the database kind 'oracleaa' for the default datasource (available: 'oracle','postgresql'). Check if it's a typo, otherwise provide a suitable JDBC driver extension, define the driver manually, or disable the JDBC datasource by adding 'quarkus.datasource.jdbc=false' to your configuration if you don't need it.
	at io.quarkus.agroal.deployment.AgroalProcessor.resolveDriver(AgroalProcessor.java:358)
	at io.quarkus.agroal.deployment.AgroalProcessor.getAggregatedConfigBuildItems(AgroalProcessor.java:332)
	at io.quarkus.agroal.deployment.AgroalProcessor.build(AgroalProcessor.java:103)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:856)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:255)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
	at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
	at java.base/java.lang.Thread.run(Thread.java:840)
	at org.jboss.threads.JBossThread.run(JBossThread.java:499)

	at io.quarkus.builder.Execution.run(Execution.java:122)
	at io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:78)
	at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:161)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:350)
	... 6 more
Caused by: io.quarkus.runtime.configuration.ConfigurationException: Unable to find a JDBC driver corresponding to the database kind 'oracleaa' for the default datasource (available: 'oracle','postgresql'). Check if it's a typo, otherwise provide a suitable JDBC driver extension, define the driver manually, or disable the JDBC datasource by adding 'quarkus.datasource.jdbc=false' to your configuration if you don't need it.
	at io.quarkus.agroal.deployment.AgroalProcessor.resolveDriver(AgroalProcessor.java:358)
	at io.quarkus.agroal.deployment.AgroalProcessor.getAggregatedConfigBuildItems(AgroalProcessor.java:332)
	at io.quarkus.agroal.deployment.AgroalProcessor.build(AgroalProcessor.java:103)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:856)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:255)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
	at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
	at java.base/java.lang.Thread.run(Thread.java:840)
	at org.jboss.threads.JBossThread.run(JBossThread.java:499)

I just thought about it... wouldn't the work you've done for active/inactive datasources let the app run till it reaches a point it wants to use a datasource and only then fail (which, in my test, is ORM attempts to get db metadata)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I've tried a bad URL (some random text), using postgres url with oracle driver (Driver does not support the provided URL), no DB running -- same results as above 😕
if I try to use some random string for db-kind, things fail at build time without getting to the Hibernate ORM stuff:

Looks like URLs are resolved on first use. Bummer. We'd need something that triggers a failure on runtime init, but when Agroal starts (presumably before Hibernate ORM).

Maybe setting the pool's min size above the max size, something like that?

I just thought about it... wouldn't the work you've done for active/inactive datasources let the app run till it reaches a point it wants to use a datasource and only then fail (which, in my test, is ORM attempts to get db metadata)?

No, my work would only disable the datasource if the JDBC url is not set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe setting the pool's min size above the max size, something like that?

mm, AgroalConnectionPoolConfigurationSupplier has validation that can throw exceptions. The validation happens when the datasource is created (DataSources#createDataSource()), which in this case is when ORM wants to create a PU, leading to:

java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus

	at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:611)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:706)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.RuntimeException: Failed to start quarkus
	at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at io.quarkus.runner.bootstrap.StartupActionImpl.run(StartupActionImpl.java:305)
	at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:224)
	at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:578)
	at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:628)
	... 1 more
Caused by: io.quarkus.runtime.configuration.ConfigurationException: Unable to find datasource '<default>' for persistence unit 'other': Error creating synthetic bean [sqqLi56D50iCdXmOjyjPSAxbLu0]: java.lang.IllegalArgumentException: Invalid min size: greater than max size
	at io.quarkus.hibernate.orm.runtime.PersistenceUnitUtil.unableToFindDataSource(PersistenceUnitUtil.java:115)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.injectDataSource(FastBootHibernatePersistenceProvider.java:392)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.buildRuntimeSettings(FastBootHibernatePersistenceProvider.java:209)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(FastBootHibernatePersistenceProvider.java:180)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:66)
	at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
	at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:160)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:61)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: jakarta.enterprise.inject.CreationException: Error creating synthetic bean [sqqLi56D50iCdXmOjyjPSAxbLu0]: java.lang.IllegalArgumentException: Invalid min size: greater than max size
	at io.agroal.api.AgroalDataSource_sqqLi56D50iCdXmOjyjPSAxbLu0_Synthetic_Bean.doCreate(Unknown Source)
	at io.agroal.api.AgroalDataSource_sqqLi56D50iCdXmOjyjPSAxbLu0_Synthetic_Bean.create(Unknown Source)
	at io.agroal.api.AgroalDataSource_sqqLi56D50iCdXmOjyjPSAxbLu0_Synthetic_Bean.create(Unknown Source)
	at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:119)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:38)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:35)
	at io.quarkus.arc.generator.Default_jakarta_enterprise_context_ApplicationScoped_ContextInstances.c11(Unknown Source)
	at io.quarkus.arc.generator.Default_jakarta_enterprise_context_ApplicationScoped_ContextInstances.computeIfAbsent(Unknown Source)
	at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:35)
	at io.quarkus.arc.impl.ClientProxies.getApplicationScopedDelegate(ClientProxies.java:23)
	at io.agroal.api.AgroalDataSource_sqqLi56D50iCdXmOjyjPSAxbLu0_Synthetic_ClientProxy.arc$delegate(Unknown Source)
	at io.agroal.api.AgroalDataSource_sqqLi56D50iCdXmOjyjPSAxbLu0_Synthetic_ClientProxy.arc_contextualInstance(Unknown Source)
	at io.quarkus.arc.ClientProxy.unwrap(ClientProxy.java:52)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.injectDataSource(FastBootHibernatePersistenceProvider.java:390)
	... 8 more
Caused by: java.lang.IllegalArgumentException: Invalid min size: greater than max size
	at io.agroal.api.configuration.supplier.AgroalConnectionPoolConfigurationSupplier.validate(AgroalConnectionPoolConfigurationSupplier.java:317)
	at io.agroal.api.configuration.supplier.AgroalConnectionPoolConfigurationSupplier.get(AgroalConnectionPoolConfigurationSupplier.java:349)
	at io.agroal.api.configuration.supplier.AgroalDataSourceConfigurationSupplier.validate(AgroalDataSourceConfigurationSupplier.java:108)
	at io.agroal.api.configuration.supplier.AgroalDataSourceConfigurationSupplier.get(AgroalDataSourceConfigurationSupplier.java:114)
	at io.quarkus.agroal.runtime.DataSources.createDataSource(DataSources.java:208)
	at io.quarkus.agroal.runtime.AgroalRecorder$3.apply(AgroalRecorder.java:65)
	at io.quarkus.agroal.runtime.AgroalRecorder$3.apply(AgroalRecorder.java:60)
	at io.agroal.api.AgroalDataSource_sqqLi56D50iCdXmOjyjPSAxbLu0_Synthetic_Bean.createSynthetic(Unknown Source)
	... 22 more

I tried to look a bit more into this, and AFAIU, if the app fails at startup we never reach this part:

recorder.handleLifecycleEvents(shutdown, launchMode.getLaunchMode(),
config.test().disableApplicationLifecycleObservers());
return new ApplicationStartBuildItem();

which means we don't fire the startup event and do not register the shutdown task to fire shutdown events ...

fireLifecycleEvent(container, new StartupEvent(), mockBeanClasses);
context.addShutdownTask(new Runnable() {
@Override
public void run() {
fireLifecycleEvent(container, new ShutdownEvent(ApplicationLifecycleManager.shutdownReason), mockBeanClasses);
}
});

if that's so then I guess we should probably keep the destroyer for the JPAConfig as well as the observer. Observer will close things nicely if all goes well, and if we end up stopping the app before it could even start then the destroyer will make an attempt to close those PUs, just in case the app failed after we've started the PUs but before the shutdown task was added...

Another thought occurred to me... could we just register a shutdown task for ORM and not deal with destroyers and observers 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm, AgroalConnectionPoolConfigurationSupplier has validation that can throw exceptions. The validation happens when the datasource is created (DataSources#createDataSource()), which in this case is when ORM wants to create a PU

This hints at another ordering problem during creation, because the intent is to have datasources created on startup:

SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = SyntheticBeanBuildItem
.configure(AgroalDataSource.class)
.addType(DATA_SOURCE)
.addType(AGROAL_DATA_SOURCE)
.scope(ApplicationScoped.class)
.qualifiers(qualifiers(dataSourceName))
.setRuntimeInit()
.unremovable()
.addInjectionPoint(ClassType.create(DotName.createSimple(DataSources.class)))
.startup()

If datasources are created when Hibernate ORM first retrieves them, it means Hibernate ORM gets initialized before Agroal, and the only reason it works is that Arc is nice enough to trigger initialization immediately if it didn't happen yet.

It feels like we could improve this as well... making sure Agroal gets initialized before Hibernate ORM?

Another thought occurred to me... could we just register a shutdown task for ORM and not deal with destroyers and observers 😄

Okay, but then we must be sure that shutdown task gets executed before Agroal gets shut down.


We're getting out of scope, though...

Eventually, what we need is a mechanism that:

  1. Initializes things in this order: Agroal => Hibernate ORM => Application
  2. Cleans up things in this order: Application => Hibernate ORM => Agroal
  3. Does not initialize Agroal/Hibernate ORM when cleaning them up -- e.g. if Agroal initialization fails, we don't want Hibernate ORM cleanup to trigger initialization of Hibernate ORM.

AFAICS, on main, we only comply with rule 3. Rule 1 is sort of irrelevant due to "lazy initialization" of Agroal -- it does lead to annoying stack traces like the one you witnessed, but that's really another issue.

To fix #34547 , we'd need to comply with rule 2.

If your PR makes sure we now comply with rule 2, and still comply with rule 3, let's merge and file a separate issue to tackle rule 1?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the status of this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say it needs a bit more time... i.e I'm sure (2) works fine as long as the app startup does not fail, I'm not so sure it works that way if there's a failure during the startup. But I haven't come up with a test to check it yet 😕

instead of relaying on a Destroyer. This way other components e.g. datasource should still be available.
@marko-bekhta marko-bekhta force-pushed the fix/i34547-observe-shutdown-instead-of-ondestroy branch from 620beda to 73b6945 Compare February 7, 2025 08:41
Copy link

quarkus-bot bot commented Feb 7, 2025

Status for workflow Quarkus Documentation CI

This is the status report for running Quarkus Documentation CI on commit 73b6945.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

Warning

There are other workflow runs running, you probably need to wait for their status before merging.

Copy link

quarkus-bot bot commented Feb 7, 2025

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit 73b6945.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@yrodiere
Copy link
Member

Superseded by #46357, closing.

@yrodiere yrodiere closed this Jul 21, 2025
@quarkus-bot quarkus-bot bot added the triage/invalid This doesn't seem right label Jul 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/hibernate-orm Hibernate ORM area/hibernate-search Hibernate Search triage/invalid This doesn't seem right

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exception on application shutdown with quarkus-hibernate-search-orm-coordination-outbox-polling

5 participants