1

Good morning, I'm trying to set up a QUARKUS project with spring, hibernate and multitenant. But not change schemas on run query? How to set up the configuration so that the query runs on the correct expected schema dynamically?

application.yml

quarkus:
 datasource:
   db-kind: postgres
   username: postgres
   password: 1234
   jdbc:
     url: jdbc:postgresql://localhost:5432/postgres
     driver: org.postgresql.Driver
 hibernate-orm:
   multitenant: SCHEMA
   dialect: org.hibernate.dialect.PostgreSQLDialect
   log:
     sql: true

Tenant Resolver


package br.com.rhino.config;

import java.util.Optional;

import io.quarkus.hibernate.orm.runtime.tenant.TenantResolver;
import io.vertx.ext.web.RoutingContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CustomTenantResolver implements TenantResolver {

    public static String DEFAULT_TENANT = "rhino";
    
    @Autowired
    RoutingContext context;

    @Override
    public String getDefaultTenantId() {
        return DEFAULT_TENANT;
    }

    @Override
    public String resolveTenantId() {
        return Optional.ofNullable(context.request().getHeader("x-tenantId")).orElse(DEFAULT_TENANT);
    }
}

Correct Intercept

Correct tenant return in debug image

LOG

 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2021-03-09 08:02:15,282 INFO  [io.qua.fly.FlywayProcessor] (build-20) Adding application migrations in path '/home/idd_acosta/freelas/rhino/rhino-api/target/classes/db/migration/maripa/' using protocol 'file'
2021-03-09 08:02:15,669 INFO  [io.qua.arc.pro.BeanProcessor] (build-24) Found unrecommended usage of private members (use package-private instead) in application beans:
    - @Inject field br.com.rhino.user.mapper.UserMapperImpl#roleMapper,
    - @Inject field br.com.rhino.user.mapper.RoleMapperImpl#permissionMapper
2021-03-09 08:02:16,591 INFO  [org.fly.cor.int.lic.VersionPrinter] (Quarkus Main Thread) Flyway Community Edition 7.5.2 by Redgate
2021-03-09 08:02:16,670 INFO  [org.fly.cor.int.dat.bas.DatabaseType] (Quarkus Main Thread) Database: jdbc:postgresql://localhost:5432/postgres (PostgreSQL 13.1)
2021-03-09 08:02:16,686 INFO  [org.fly.cor.int.com.DbClean] (Quarkus Main Thread) Successfully dropped pre-schema database level objects (execution time 00:00.000s)
2021-03-09 08:02:16,709 INFO  [org.fly.cor.int.com.DbClean] (Quarkus Main Thread) Successfully dropped schema "maripa" (execution time 00:00.021s)
2021-03-09 08:02:16,710 INFO  [org.fly.cor.int.com.DbClean] (Quarkus Main Thread) Successfully dropped schema " bicas" (execution time 00:00.001s)
2021-03-09 08:02:16,712 INFO  [org.fly.cor.int.com.DbClean] (Quarkus Main Thread) Successfully dropped schema " rhino" (execution time 00:00.001s)
2021-03-09 08:02:16,712 INFO  [org.fly.cor.int.com.DbClean] (Quarkus Main Thread) Successfully dropped post-schema database level objects (execution time 00:00.000s)
2021-03-09 08:02:16,714 INFO  [org.fly.cor.int.lic.VersionPrinter] (Quarkus Main Thread) Flyway Community Edition 7.5.2 by Redgate
2021-03-09 08:02:16,718 INFO  [org.fly.cor.int.dat.bas.Schema] (Quarkus Main Thread) Creating schema "maripa" ...
2021-03-09 08:02:16,718 INFO  [org.fly.cor.int.dat.bas.Schema] (Quarkus Main Thread) Creating schema " bicas" ...
2021-03-09 08:02:16,719 INFO  [org.fly.cor.int.dat.bas.Schema] (Quarkus Main Thread) Creating schema " rhino" ...
2021-03-09 08:02:16,721 INFO  [org.fly.cor.int.sch.JdbcTableSchemaHistory] (Quarkus Main Thread) Creating Schema History table "maripa"."flyway_schema_history" ...
2021-03-09 08:02:16,755 INFO  [org.fly.cor.int.com.DbMigrate] (Quarkus Main Thread) Current version of schema "maripa": null
2021-03-09 08:02:16,762 INFO  [org.fly.cor.int.com.DbMigrate] (Quarkus Main Thread) Migrating schema "maripa" to version "1.0.1 - start structure maripa"
2021-03-09 08:02:16,813 INFO  [org.fly.cor.int.com.DbMigrate] (Quarkus Main Thread) Successfully applied 1 migration to schema "maripa" (execution time 00:00.066s)
2021-03-09 08:02:17,120 INFO  [io.qua.sch.run.SimpleScheduler] (Quarkus Main Thread) No scheduled business methods found - Simple scheduler will not be started
2021-03-09 08:02:17,194 INFO  [io.quarkus] (Quarkus Main Thread) rhino-api 1.0.0-SNAPSHOT on JVM (powered by Quarkus 1.12.1.Final) started in 2.714s. Listening on: http://localhost:8080
2021-03-09 08:02:17,194 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2021-03-09 08:02:17,194 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, config-yaml, flyway, hibernate-orm, hibernate-orm-panache, hibernate-orm-rest-data-panache, jdbc-postgresql, micrometer, mutiny, narayana-jta, resteasy, resteasy-jackson, scheduler, security, smallrye-context-propagation, spring-data-jpa, spring-di, spring-scheduled, spring-security, spring-web]

Hibernate: 
    select
        user0_.id as id1_7_,
        user0_.dt_creation as dt_creat2_7_,
        user0_.email as email3_7_,
        user0_.password as password4_7_,
        user0_.dt_update as dt_updat5_7_,
        user0_.username as username6_7_ 
    from
        user user0_
2021-03-09 08:09:33,430 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (executor-thread-1) SQL Error: 0, SQLState: 42703
2021-03-09 08:09:33,430 ERROR [org.hib.eng.jdb.spi.SqlExceptionHelper] (executor-thread-1) ERROR: column user0_.id does not exist
  Posição: 8
2021-03-09 08:09:33,441 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /user failed, error id: 0866564b-c6ab-43be-b245-ab70add72f26-1: org.jboss.resteasy.spi.UnhandledException: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)
    at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:218)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:519)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
    at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:138)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:41)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:93)
    at io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:231)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2415)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
    at java.base/java.lang.Thread.run(Thread.java:834)
    at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1602)
    at org.hibernate.query.Query.getResultList(Query.java:165)
    at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.list(CommonPanacheQueryImpl.java:230)
    at io.quarkus.hibernate.orm.panache.runtime.PanacheQueryImpl.list(PanacheQueryImpl.java:149)
    at br.com.rhino.user.service.UserService.findAllUsers(UserService.java:73)
    at br.com.rhino.user.controller.UserController.findAll(UserController.java:36)
    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 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
    at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:643)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:507)
    at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:457)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:459)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:419)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:393)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
    ... 18 more
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:103)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:67)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2303)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2056)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2018)
    at org.hibernate.loader.Loader.doQuery(Loader.java:948)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
    at org.hibernate.loader.Loader.doList(Loader.java:2849)
    at org.hibernate.loader.Loader.doList(Loader.java:2831)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2663)
    at org.hibernate.loader.Loader.list(Loader.java:2658)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506)
    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:1414)
    at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1625)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1593)
    ... 38 more
Caused by: org.postgresql.util.PSQLException: ERROR: column user0_.id does not exist
  Posição: 8
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2553)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2285)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:323)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:473)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:393)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164)
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114)
    at io.agroal.pool.wrapper.PreparedStatementWrapper.executeQuery(PreparedStatementWrapper.java:76)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57)
    ... 53 more

Obs.: Sorry by my english! :)

1 Answers1

0

Not sure how your application code looks exactly, but it seems that you follow the documentation: https://quarkus.io/guides/hibernate-orm#multitenancy

If your entity does not specify an explicit schema, I would suggest you create a bug report with a reproducer: https://github.com/quarkusio/quarkus/issues/new?assignees=&labels=kind%2Fbug&template=bug_report.md&title=

Christian Beikov
  • 15,141
  • 2
  • 32
  • 58