我尝试按照Quarkus hibernate-orm doc为我的Quarkus应用程序添加多租户支持(请参阅上一节)。
我在application.properties
中有我的CustomTenantResolver
类和配置,有多个数据源,但没有命名的持久化单元,如下所示:
# 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访问都会给出此异常:
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中的调度程序如何-它如何支持调度作业中的多租户?
谢谢你的帮助。
发布于 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
实现之前希望请求上下文处于活动状态,如下所示:
// Make sure that we're in a request
if (!Arc.container().requestContext().isActive()) {
return null;
}
TenantResolver resolver = tenantResolver(persistenceUnitName);
String tenantId = resolver.resolveTenantId();
我在我的应用程序上解决了这个问题,首先,在JMS使用者上启用请求上下文:
Arc.container().requestContext().activate();
其次,使用ThreadLocal
将当前租户id“传递”给稍后将由Hibernate调用的TenantResolver (通过HibernateCurrentTenantIdentifierResolver实例):
CurrentTenantLocal.setCurrentTenantId("public");
在我的TenantResolver
( implements TenantResolver
的类)上,当租户来自WebRequest时,我从注入的JsonWebToken jwt
解析租户,或者在从WebRequest消费时使用ThreadLocal:
if ( CurrentTenantLocal.getCurrentTenantId() != null ) {
return CurrentTenantLocal.getCurrentTenantId();
}
注意事项:
https://stackoverflow.com/questions/66911782
复制相似问题