首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Quarkus:回调中未指定租户标识符

Quarkus:回调中未指定租户标识符
EN

Stack Overflow用户
提问于 2021-04-02 05:29:10
回答 1查看 139关注 0票数 0

我尝试按照Quarkus hibernate-orm doc为我的Quarkus应用程序添加多租户支持(请参阅上一节)。

我在application.properties中有我的CustomTenantResolver类和配置,有多个数据源,但没有命名的持久化单元,如下所示:

代码语言:javascript
运行
复制
# Default data source
quarkus.hibernate-orm.datasource=master
quarkus.hibernate-orm.database.generation=none

quarkus.hibernate-orm.multitenant=DATABASE

# ----- Tenant 'master' (default) ---------------
quarkus.datasource."master".db-kind=postgresql
quarkus.datasource."master".username=postgres
quarkus.datasource."master".password=password
quarkus.datasource."master".jdbc.url=jdbc:postgresql://localhost:5432/db_master

# ----- Tenant 'test' ---------------------------
quarkus.datasource.test.db-kind=postgresql
quarkus.datasource.test.username=postgres
quarkus.datasource.test.password=password
quarkus.datasource.test.jdbc.url=jdbc:postgresql://localhost:5432/db_test

对于Web服务API函数,一切工作正常--基于传入的web服务调用,我可以提取并提供租户标识符用于DB访问。

问题是,我的应用程序还需要使用回调方法来侦听来自Apache Pulsar队列的消息。当消息传入并触发此回调时,此方法中的任何DB访问都会给出此异常:

代码语言:javascript
运行
复制
SessionFactory configured for multi-tenancy, but no tenant identifier specified: org.hibernate.HibernateException: SessionFactory configured for multi-tenancy, but no tenant identifier specified
    at org.hibernate.internal.AbstractSharedSessionContract.<init>(AbstractSharedSessionContract.java:172)
    at org.hibernate.internal.AbstractSessionImpl.<init>(AbstractSessionImpl.java:29)
    at org.hibernate.internal.SessionImpl.<init>(SessionImpl.java:221)
    at org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1282)
    at org.hibernate.internal.SessionFactoryImpl.openSession(SessionFactoryImpl.java:472)
    at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.acquireSession(TransactionScopedSession.java:86)
    at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.persist(TransactionScopedSession.java:138)
    at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.persist(ForwardingSession.java:53)
... (snipped)

显然,我的CustomTenantResolver类在这个侦听器回调期间没有被调用,因为回调是另一个新线程,因此没有提供租户id。

我错过什么了吗?Quarkus中的调度程序如何-它如何支持调度作业中的多租户?

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

发布于 2021-06-21 22:09:43

在从JMS拉取消息时,我遇到了类似的问题。问题的原因是io.quarkus.hibernate.orm.runtime.tenant.HibernateCurrentTenantIdentifierResolver ( implements CurrentTenantIdentifierResolver和文档所说的Maps from the Quarkus {@link TenantResolver} to the Hibernate {@link CurrentTenantIdentifierResolver} model )在调用我们的TenantResolver实现之前希望请求上下文处于活动状态,如下所示:

代码语言:javascript
运行
复制
        // Make sure that we're in a request
        if (!Arc.container().requestContext().isActive()) {
            return null;
        }
        TenantResolver resolver = tenantResolver(persistenceUnitName);
        String tenantId = resolver.resolveTenantId();

我在我的应用程序上解决了这个问题,首先,在JMS使用者上启用请求上下文:

代码语言:javascript
运行
复制
Arc.container().requestContext().activate();

其次,使用ThreadLocal将当前租户id“传递”给稍后将由Hibernate调用的TenantResolver (通过HibernateCurrentTenantIdentifierResolver实例):

代码语言:javascript
运行
复制
  CurrentTenantLocal.setCurrentTenantId("public");

在我的TenantResolver ( implements TenantResolver的类)上,当租户来自WebRequest时,我从注入的JsonWebToken jwt解析租户,或者在从WebRequest消费时使用ThreadLocal:

代码语言:javascript
运行
复制
    if ( CurrentTenantLocal.getCurrentTenantId() != null ) {
      return CurrentTenantLocal.getCurrentTenantId();
    }

注意事项:

  • 请注意,我还没有详尽地研究激活请求上下文可能带来的副作用……但到目前为止,我还没有遇到任何问题。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66911782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档