Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StackOverflowException is thrown when read database config in TenantConnectionResolver #19563

Closed
hanzhenliang opened this issue Aug 22, 2021 · 13 comments
Labels
area/kotlin kind/bug Something isn't working

Comments

@hanzhenliang
Copy link

Describe the bug

I have a default datasource which stores tenant configurations including database config, and store other data per tenant per database. I tried to read database config in TenantConnectionResolver, but got StackOverflowException at the end.

Caused by: java.lang.StackOverflowError
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:445)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:405)
	at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
	at org.hibernate.query.Query.getResultList(Query.java:165)
Caused by: java.lang.StackOverflowError

	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.firstResult(CommonPanacheQueryImpl.java:263)
	at io.quarkus.hibernate.orm.panache.kotlin.runtime.PanacheQueryImpl.firstResult(PanacheQueryImpl.kt:117)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository.findByTenant(TenantRepository.kt:29)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass.findByTenant$$superforward1(TenantPanacheRepository_Subclass.zig:1695)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass$$function$$3.apply(TenantPanacheRepository_Subclass$$function$$3.zig:33)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass.findByTenant(TenantPanacheRepository_Subclass.zig:2759)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_ClientProxy.findByTenant(TenantPanacheRepository_ClientProxy.zig:2064)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver.resolve(MultiTenantConnectionResolver.kt:16)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass.resolve$$superforward1(MultiTenantConnectionResolver_Subclass.zig:160)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass$$function$$2.apply(MultiTenantConnectionResolver_Subclass$$function$$2.zig:33)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass.resolve(MultiTenantConnectionResolver_Subclass.zig:323)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_ClientProxy.resolve(MultiTenantConnectionResolver_ClientProxy.zig:217)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.resolveConnectionProvider(HibernateMultiTenantConnectionProvider.java:78)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.selectConnectionProvider(HibernateMultiTenantConnectionProvider.java:52)
	at org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider.getConnection(AbstractMultiTenantConnectionProvider.java:36)
	at org.hibernate.internal.ContextualJdbcConnectionAccess.obtainConnection(ContextualJdbcConnectionAccess.java:43)
	at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:108)
	at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:138)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:50)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
	at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2115)
	at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2052)
	at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2030)
	at org.hibernate.loader.Loader.doQuery(Loader.java:956)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
	at org.hibernate.loader.Loader.doList(Loader.java:2861)
	at org.hibernate.loader.Loader.doList(Loader.java:2843)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2675)
	at org.hibernate.loader.Loader.list(Loader.java:2670)
	at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:540)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
	at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1443)
	at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649)
	at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
	at org.hibernate.query.Query.getResultList(Query.java:165)
	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.firstResult(CommonPanacheQueryImpl.java:263)
	at io.quarkus.hibernate.orm.panache.kotlin.runtime.PanacheQueryImpl.firstResult(PanacheQueryImpl.kt:117)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository.findByTenant(TenantRepository.kt:29)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass.findByTenant$$superforward1(TenantPanacheRepository_Subclass.zig:1695)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass$$function$$3.apply(TenantPanacheRepository_Subclass$$function$$3.zig:33)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass.findByTenant(TenantPanacheRepository_Subclass.zig:2759)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_ClientProxy.findByTenant(TenantPanacheRepository_ClientProxy.zig:2064)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver.resolve(MultiTenantConnectionResolver.kt:16)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass.resolve$$superforward1(MultiTenantConnectionResolver_Subclass.zig:160)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass$$function$$2.apply(MultiTenantConnectionResolver_Subclass$$function$$2.zig:33)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass.resolve(MultiTenantConnectionResolver_Subclass.zig:323)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_ClientProxy.resolve(MultiTenantConnectionResolver_ClientProxy.zig:217)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.resolveConnectionProvider(HibernateMultiTenantConnectionProvider.java:78)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.selectConnectionProvider(HibernateMultiTenantConnectionProvider.java:52)
	at org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider.getConnection(AbstractMultiTenantConnectionProvider.java:36)
	at org.hibernate.internal.ContextualJdbcConnectionAccess.obtainConnection(ContextualJdbcConnectionAccess.java:43)
	at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:108)
	at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:138)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:50)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
	at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2115)
	at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2052)
	at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2030)
	at org.hibernate.loader.Loader.doQuery(Loader.java:956)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
	at org.hibernate.loader.Loader.doList(Loader.java:2861)
	at org.hibernate.loader.Loader.doList(Loader.java:2843)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2675)
	at org.hibernate.loader.Loader.list(Loader.java:2670)
	at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:540)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
	at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1443)
	at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649)
	at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
	at org.hibernate.query.Query.getResultList(Query.java:165)
	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.firstResult(CommonPanacheQueryImpl.java:263)
	at io.quarkus.hibernate.orm.panache.kotlin.runtime.PanacheQueryImpl.firstResult(PanacheQueryImpl.kt:117)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository.findByTenant(TenantRepository.kt:29)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass.findByTenant$$superforward1(TenantPanacheRepository_Subclass.zig:1695)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass$$function$$3.apply(TenantPanacheRepository_Subclass$$function$$3.zig:33)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass.findByTenant(TenantPanacheRepository_Subclass.zig:2759)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_ClientProxy.findByTenant(TenantPanacheRepository_ClientProxy.zig:2064)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver.resolve(MultiTenantConnectionResolver.kt:16)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass.resolve$$superforward1(MultiTenantConnectionResolver_Subclass.zig:160)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass$$function$$2.apply(MultiTenantConnectionResolver_Subclass$$function$$2.zig:33)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass.resolve(MultiTenantConnectionResolver_Subclass.zig:323)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_ClientProxy.resolve(MultiTenantConnectionResolver_ClientProxy.zig:217)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.resolveConnectionProvider(HibernateMultiTenantConnectionProvider.java:78)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.selectConnectionProvider(HibernateMultiTenantConnectionProvider.java:52)
	at org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider.getConnection(AbstractMultiTenantConnectionProvider.java:36)
	at org.hibernate.internal.ContextualJdbcConnectionAccess.obtainConnection(ContextualJdbcConnectionAccess.java:43)
	at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:108)
	at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:138)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:50)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
	at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
	at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2115)
	at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2052)
	at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2030)
	at org.hibernate.loader.Loader.doQuery(Loader.java:956)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
	at org.hibernate.loader.Loader.doList(Loader.java:2861)
	at org.hibernate.loader.Loader.doList(Loader.java:2843)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2675)
	at org.hibernate.loader.Loader.list(Loader.java:2670)
	at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:540)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
	at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1443)
	at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649)
	at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
	at org.hibernate.query.Query.getResultList(Query.java:165)
	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.firstResult(CommonPanacheQueryImpl.java:263)
	at io.quarkus.hibernate.orm.panache.kotlin.runtime.PanacheQueryImpl.firstResult(PanacheQueryImpl.kt:117)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository.findByTenant(TenantRepository.kt:29)

Expected behavior

StackOverflowException is thrown.

Actual behavior

The PanacheRepository injected in TenantConnectionResolver should use default datasource instead of resolving from TenantConnectionResolver.

How to Reproduce?

https://github.com/quarkusio/quarkus-quickstarts/tree/main/hibernate-orm-multi-tenancy-quickstart

Read database config in TenantConnectionResolver.

Output of uname -a or ver

Darwin C02T81GVG8WL 19.6.0 Darwin Kernel Version 19.6.0: Tue Jun 22 19:49:55 PDT 2021; root:xnu-6153.141.35~1/RELEASE_X86_64 x86_64

Output of java -version

openjdk version "11.0.9.1" 2020-11-04 OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.9.1+1) OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.9.1+1, mixed mode)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.1.0.Final

Build tool (ie. output of mvnw --version or gradlew --version)

------------------------------------------------------------ Gradle 6.9 ------------------------------------------------------------ Build time: 2021-05-07 07:28:53 UTC Revision: afe2e24ababc7b0213ccffff44970aa18035fc0e Kotlin: 1.4.20 Groovy: 2.5.12 Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020 JVM: 11.0.9.1 (AdoptOpenJDK 11.0.9.1+1) OS: Mac OS X 10.15.7 x86_64

Additional information

No response

@hanzhenliang hanzhenliang added the kind/bug Something isn't working label Aug 22, 2021
@quarkus-bot
Copy link

quarkus-bot bot commented Aug 22, 2021

/cc @evanchooly

@gastaldi
Copy link
Contributor

@hanzhenliang can you provide a sample on how you are reading the database from your TenantConnectionResolver ? I believe you need to avoid using the Panache API in this layer, preferably using the DataSource directly.

@hanzhenliang
Copy link
Author

@gastaldi I just injected the panache repository in my custom TenantConnectionResolver.
Here is my configs:

quarkus:
  hibernate-orm:
    multitenant: DATABASE
  datasource:
    db-kind: mysql
    username: ***
    password: ***
    jdbc:
      url: jdbc:mysql://localhost:3306/***
      max-size: 10

@gastaldi
Copy link
Contributor

Right, so what happens if you @Inject DataSource instead? I don't think you are allowed to use any Panache features inside this impl, we should probably detect that during build time and fail the build

@hanzhenliang
Copy link
Author

I don't have StackOverflow exception any more with injecting DataSource. But got an error in build time:

021-08-23 21:39:46,696 ERROR [io.ver.cor.net.imp.ConnectionBase] (vert.x-eventloop-thread-0) Connection reset by peer
2021-08-23 21:39:46,700 ERROR [io.ver.cor.htt.imp.HttpClientRequestImpl] (vert.x-eventloop-thread-0) java.io.IOException: Connection reset by peer
2021-08-23 21:39:46,703 ERROR [io.ver.cor.htt.imp.HttpClientRequestImpl] (vert.x-eventloop-thread-0) io.vertx.core.VertxException: Connection was closed
2021-08-23 21:39:46,766 WARN  [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: <default>) HHH000342: Could not obtain connection to query metadata: javax.enterprise.context.ContextNotActiveException
	at io.quarkus.arc.impl.ClientProxies.getDelegate(ClientProxies.java:40)
	at ai.bidwise.backend.account.resolver.MultiTenantResolver_ClientProxy.arc$delegate(MultiTenantResolver_ClientProxy.zig:42)
	at ai.bidwise.backend.account.resolver.MultiTenantResolver_ClientProxy.getDefaultTenantId(MultiTenantResolver_ClientProxy.zig:159)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.getAnyConnectionProvider(HibernateMultiTenantConnectionProvider.java:37)
	at org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider.getAnyConnection(AbstractMultiTenantConnectionProvider.java:26)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$MultiTenantConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:208)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:107)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.boot.internal.SessionFactoryOptionsBuilder.<init>(SessionFactoryOptionsBuilder.java:263)
	at io.quarkus.hibernate.orm.runtime.recording.PrevalidatedQuarkusMetadata.buildSessionFactoryOptionsBuilder(PrevalidatedQuarkusMetadata.java:69)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:69)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:67)
	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:149)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:58)
	at java.base/java.lang.Thread.run(Thread.java:834)

@hanzhenliang
Copy link
Author

hanzhenliang commented Aug 23, 2021

I should have explained what I'm doing a little bit earlier. I'm building a multiple tenant application which will have a default DataSource to store all tenant configurations, and each tenant will have an isolated database to store their data.

Every time the TenantConnectionResolver resolves, I need to query the default DataSource to get the tenant configurations, which means I will need to use the default tenant in current tenant.

@gastaldi
Copy link
Contributor

Right, so you can't use the Panache API in there because using it would require triggering the same TenantConnectionResolver and that would give you this error. I am not sure how you implemented your ai.bidwise.backend.account.resolver.MultiTenantResolver class, can you share it?

@gastaldi
Copy link
Contributor

This error looks similar to #19467

@hanzhenliang
Copy link
Author

Here is the MultiTenantResolver:

@RequestScoped
class MultiTenantResolver : TenantResolver {

    @Inject
    lateinit var routingContext: RoutingContext

    override fun getDefaultTenantId(): String = TenantPersistenceUnit.NAME

    override fun resolveTenantId(): String = routingContext.tenant ?: TenantPersistenceUnit.NAME

}

@hanzhenliang
Copy link
Author

This error looks similar to #19467

The same issue.

@gastaldi
Copy link
Contributor

We'll close this issue and track in #19467. Thanks for your feedback!

@hanzhenliang
Copy link
Author

Hi, I tried another approach that I created 2 persistence units, one is default which stores the tenant config, the other is specified for tenants. I don't have StackOverflowException but the same ContextIsNotActiveException.

The stacktrace:

2021-08-25 08:59:26,512 WARN  [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: tenant) HHH000342: Could not obtain connection to query metadata: javax.enterprise.context.ContextNotActiveException
	at io.quarkus.arc.impl.ClientProxies.getDelegate(ClientProxies.java:40)
	at io.quarkus.hibernate.orm.runtime.RequestScopedSessionHolder_ClientProxy.arc$delegate(RequestScopedSessionHolder_ClientProxy.zig:42)
	at io.quarkus.hibernate.orm.runtime.RequestScopedSessionHolder_ClientProxy.getOrCreateSession(RequestScopedSessionHolder_ClientProxy.zig:102)
	at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.acquireSession(TransactionScopedSession.java:104)
	at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.createQuery(TransactionScopedSession.java:344)
	at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.createQuery(ForwardingSession.java:168)
	at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.createQuery(ForwardingSession.java:47)
	at org.hibernate.Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.createQuery(Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.zig:1916)
	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createBaseQuery(CommonPanacheQueryImpl.java:339)
	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createQuery(CommonPanacheQueryImpl.java:315)
	at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.firstResult(CommonPanacheQueryImpl.java:260)
	at io.quarkus.hibernate.orm.panache.kotlin.runtime.PanacheQueryImpl.firstResult(PanacheQueryImpl.kt:117)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository.findTenantByEmailOrName(TenantRepository.kt:23)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass.findTenantByEmailOrName$$superforward1(TenantPanacheRepository_Subclass.zig:1669)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass$$function$$3.apply(TenantPanacheRepository_Subclass$$function$$3.zig:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:51)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_Subclass.findTenantByEmailOrName(TenantPanacheRepository_Subclass.zig:2722)
	at ai.bidwise.backend.account.repository.TenantPanacheRepository_ClientProxy.findTenantByEmailOrName(TenantPanacheRepository_ClientProxy.zig:824)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver.resolve(MultiTenantConnectionResolver.kt:29)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass.resolve$$superforward1(MultiTenantConnectionResolver_Subclass.zig:226)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass$$function$$3.apply(MultiTenantConnectionResolver_Subclass$$function$$3.zig:33)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:51)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_Subclass.resolve(MultiTenantConnectionResolver_Subclass.zig:488)
	at ai.bidwise.backend.account.resolver.MultiTenantConnectionResolver_ClientProxy.resolve(MultiTenantConnectionResolver_ClientProxy.zig:248)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.resolveConnectionProvider(HibernateMultiTenantConnectionProvider.java:78)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.selectConnectionProvider(HibernateMultiTenantConnectionProvider.java:52)
	at io.quarkus.hibernate.orm.runtime.tenant.HibernateMultiTenantConnectionProvider.getAnyConnectionProvider(HibernateMultiTenantConnectionProvider.java:42)
	at org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider.getAnyConnection(AbstractMultiTenantConnectionProvider.java:26)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$MultiTenantConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:208)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:107)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.boot.internal.SessionFactoryOptionsBuilder.<init>(SessionFactoryOptionsBuilder.java:263)
	at io.quarkus.hibernate.orm.runtime.recording.PrevalidatedQuarkusMetadata.buildSessionFactoryOptionsBuilder(PrevalidatedQuarkusMetadata.java:69)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:69)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:67)
	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:149)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:58)
	at java.base/java.lang.Thread.run(Thread.java:834)

The config:

hibernate-orm:
    packages: ***
    tenant:
      datasource: <default>
      multitenant: DATABASE
      packages: ***
  datasource:
    db-kind: mysql
    username: ***
    password: ***
    jdbc:
      url: jdbc:mysql://localhost:3306/***
      max-size: 2

@gastaldi
Copy link
Contributor

@hanzhenliang Yes, that is fixed in Quarkus 2.2.0 Final

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/kotlin kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants