org.flowable.common.engine.api.FlowableException: Could not find a dataSource for tenant null

I am using flowable multitenant engine. Shared engine multiple schema.

Engine is starting fine but when I try to start a process I am getting error below.

org.flowable.common.engine.api.FlowableException: Could not find a dataSource for tenant null
at org.flowable.common.engine.impl.cfg.multitenant.TenantAwareDataSource.getCurrentDataSource(TenantAwareDataSource.java:68) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.cfg.multitenant.TenantAwareDataSource.getConnection(TenantAwareDataSource.java:56) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:138) ~[mybatis-3.5.3.jar:3.5.3]
at org.apache.ibatis.transaction.jdbc.JdbcTransaction.getConnection(JdbcTransaction.java:60) ~[mybatis-3.5.3.jar:3.5.3]
at org.apache.ibatis.session.defaults.DefaultSqlSession.getConnection(DefaultSqlSession.java:297) ~[mybatis-3.5.3.jar:3.5.3]
at org.flowable.common.engine.impl.db.DbSqlSessionFactory.openSession(DbSqlSessionFactory.java:96) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.interceptor.CommandContext.getSession(CommandContext.java:246) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext.(StandaloneMybatisTransactionContext.java:48) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.cfg.standalone.StandaloneMybatisTransactionContextFactory.openTransactionContext(StandaloneMybatisTransactionContextFactory.java:26) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:47) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:72) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) ~[flowable-engine-common-6.5.0.jar:6.5.0]
at org.flowable.engine.impl.RuntimeServiceImpl.startProcessInstance(RuntimeServiceImpl.java:732) ~[flowable-engine-6.5.0.jar:6.5.0]
at org.flowable.engine.impl.runtime.ProcessInstanceBuilderImpl.start(ProcessInstanceBuilderImpl.java:205) ~[flowable-engine-6.5.0.jar:6.5.0]
at com.swapstech.galaxy.workflow.service.WorkFlowServiceImpl.startWorkFlowAsync(WorkFlowServiceImpl.java:51) ~[classes/:na]
at com.swapstech.galaxy.workflow.service.WorkFlowServiceImpl$$FastClassBySpringCGLIB$$6873dbe7.invoke() ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_181]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_181]

My engine configuration

@Bean
public MultiSchemaMultiTenantProcessEngineConfiguration processEngineConfigurationImpl() {
BankOSTenantHolder tenantInfoHolder= new BankOSTenantHolder();
tenantInfoHolder.addTenant(tenants);
MultiSchemaMultiTenantProcessEngineConfiguration config= new MultiSchemaMultiTenantProcessEngineConfiguration(tenantInfoHolder);
config.setDatabaseType(MultiSchemaMultiTenantProcessEngineConfiguration.DATABASE_TYPE_MYSQL);
config.setDatabaseSchemaUpdate(MultiSchemaMultiTenantProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
config.setAsyncExecutorActivate(true);
config.setDisableIdmEngine(true);
config.setDisableEventRegistry(true);
config.setJpaEntityManagerFactory(localContainerEntityManagerFactoryBean.getObject());
config.setTransactionContextFactory(transactionContextFactory(platformTransactionManager));
if (sharedExecutor) {
config.setAsyncExecutor(new SharedExecutorServiceAsyncExecutor(tenantInfoHolder));
} else {
config.setAsyncExecutor(new ExecutorPerTenantAsyncExecutor(tenantInfoHolder));
}
return config;
}

@Bean
public ProcessEngine buildProcessEngine(MultiSchemaMultiTenantProcessEngineConfiguration config) {
for (String tenant : tenants) {
config.registerTenant(tenant,createDataSource(tenant));
}
return config.buildProcessEngine();
}

And this is how I am starting the flow

ProcessInstance processInstance = null;
processInstance = processEngine.getRuntimeService().createProcessInstanceBuilder()
.variables(workFlowModelMap)
.processDefinitionKey(processInstanceKey)
.predefineProcessInstanceId(processInstId)
.tenantId(tenant)
.start();

Looks like we do not get the tenantID in TenantAwareDataSource. I referred to existing post but could not get anything.
https://forum.flowable.org/t/getting-tenant-id-as-null-from-tenantawaredatasource-in-multi-tenancy-mode/5079/7
I see TransactionContextInterceptor tries to open the connection and it fails.
I will appreciate any pointers.

Thanks.

Pl

Anyone facing same issue? I am stuck on this.

When starting the process instance, do you set the current tenantId? The TenantAwareDataSource can’t know which tenant it needs to pick. It won’t pick it up from the .tenantId() in the start method.
See example here: https://github.com/flowable/flowable-engine/blob/master/modules/flowable-engine/src/test/java/org/flowable/engine/test/cfg/multitenant/MultiTenantProcessEngineTest.java#L152

1 Like

I am using below code

processInstance = processEngine.getRuntimeService().createProcessInstanceBuilder()
.variables(workFlowModelMap)
.processDefinitionKey(processInstanceKey)
.predefineProcessInstanceId(processInstId)
.tenantId(tenant)
.startAsync();

I was assuming if I set the tenantId, it would also update the TenantInfoHolder.

I reviewed the test case, looks like we are we need use same TenantInfoHolder object globally. We have to set tenant manually before starting process and clear after completion of process.

One question : What will be the us of tenantId set in the process instance.

Solved into another post https://forum.flowable.org/t/tenantawaredatasource-how-it-updated-the-current-tenant-id/6840/2