场景:
公司springboot项目集成 ,数据库使用oralce,首次加载flowable,自加载建表成功,功能正常,但是切换oracle用户,再首次建表时报错如下:
2023-12-11 17:58:03.578 WARN 24280 --- [ main] c.b.m.core.metadata.TableInfoHelper : Can not find table primary key in Class: "java.util.Map".
2023-12-11 17:58:03.578 WARN 24280 --- [ main] c.b.m.core.injector.DefaultSqlInjector : interface java.util.Map ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
2023-12-11 17:58:04.425 INFO 24280 --- [ main] o.f.s.b.e.EventRegistryAutoConfiguration : No deployment resources were found for autodeployment
2023-12-11 17:58:04.998 INFO 24280 --- [ main] o.f.s.SpringProcessEngineConfiguration : Found 2 Engine Configurators in total:
2023-12-11 17:58:04.998 INFO 24280 --- [ main] o.f.s.SpringProcessEngineConfiguration : class org.flowable.eventregistry.spring.configurator.SpringEventRegistryConfigurator (priority:100000)
2023-12-11 17:58:04.998 INFO 24280 --- [ main] o.f.s.SpringProcessEngineConfiguration : class org.flowable.idm.engine.configurator.IdmEngineConfigurator (priority:150000)
2023-12-11 17:58:04.998 INFO 24280 --- [ main] o.f.s.SpringProcessEngineConfiguration : Executing beforeInit() of class org.flowable.eventregistry.spring.configurator.SpringEventRegistryConfigurator (priority:100000)
2023-12-11 17:58:05.005 INFO 24280 --- [ main] o.f.s.SpringProcessEngineConfiguration : Executing beforeInit() of class org.flowable.idm.engine.configurator.IdmEngineConfigurator (priority:150000)
2023-12-11 17:58:06.019 INFO 24280 --- [ main] o.f.s.SpringProcessEngineConfiguration : Executing configure() of class org.flowable.eventregistry.spring.configurator.SpringEventRegistryConfigurator (priority:100000)
2023-12-11 17:58:23.998 ERROR 24280 --- [ main] o.f.c.e.impl.db.CommonDbSchemaManager : Could not get property from table ACT_GE_PROPERTY
java.sql.SQLSyntaxErrorException: ORA-00942: 表或视图不存在
2023-12-11 17:58:24.003 INFO 24280 --- [ main] o.f.c.e.impl.db.CommonDbSchemaManager : upgrading flowable common schema from 6.1.2.0 to 6.5.0.6
2023-12-11 17:58:24.003 INFO 24280 --- [ main] o.f.c.e.impl.db.CommonDbSchemaManager : Upgrade needed: 6120 -> 6200. Looking for schema update resource for component 'common'
2023-12-11 17:58:24.005 INFO 24280 --- [ main] o.f.c.e.impl.db.CommonDbSchemaManager : performing upgrade on common with resource org/flowable/common/db/upgrade/flowable.all.upgradestep.6120.to.6200.common.sql
2023-12-11 17:58:24.151 ERROR 24280 --- [ main] o.f.c.e.impl.db.CommonDbSchemaManager : problem during schema upgrade, statement insert into ACT_GE_PROPERTY values ('common.schema.version', '6.2.0.0', 1)
java.sql.SQLSyntaxErrorException: ORA-00942: 表或视图不存在
分析可知,问题在于,自建表前查询表是否存在时,查询所有用户的表,导致新用户跳出建表,查询业务表时报错。
mysql 可以使用添加配置nullCatalogMeansCurrent=true配置,但是oracle 的database-schema无效
1查询错误位置
首先根据报错日志找到,基本配置文件入口
package org.flowable.eventregistry.spring.configurator;
public void configure(AbstractEngineConfiguration engineConfiguration)
2调用方法位置:
.m2\repository\org\flowable\flowable-engine-common\6.5.0\flowable-engine-common-6.5.0.jar!\org\flowable\common\engine\impl\db\AbstractSqlScriptBasedDbSchemaManager.class
调用方法:
》》public String getProperty(String propertyName)
》》public boolean isTablePresent(String tableName)
try {
tables = databaseMetaData.getTables(catalog, schema, tableName, JDBC_METADATA_TABLE_TYPES);
var10 = tables.next();
} finally {
try {
if (tables != null) {
tables.close();
}
} catch (Exception var18) {
this.logger.error("Error closing meta data tables", var18);
}
}
3调用位置
.m2\repository\com\oracle\ojdbc6\11.2.0.3\ojdbc6-11.2.0.3.jar!\oracle\jdbc\OracleDatabaseMetaData.class
调用的public synchronized ResultSet getTables(String var1, String var2, String var3, String[] var4) throws SQLException
最终返回OracleResultSet对象
OracleResultSet var24 = (OracleResultSet)var23.executeQuery();
var24.closeStatementOnClose();
return var24;
执行的sql大致拆解为:
SELECT NULL AS table_cat,
o.owner AS table_schem,
o.object_name AS table_name,
o.object_type AS table_type,
NULL AS remarks,
o.owner, o.object_name
FROM all_objects o
WHERE 1=1 -- o.owner LIKE :1 ESCAPE '/'
AND o.object_name LIKE 'ACT_GE_PROPERTY'
AND o.object_type IN ('xxx', 'TABLE')
如此oracle默认下查询了多个用户的表空间,
PreparedStatement var23 = this.connection.prepareStatement(var22);
var23.setString(1, var2 == null ? "%" : var2);
var23.setString(2, var3 == null ? "%" : var3);
if (var12 && this.connection.getRestrictGetTables()) {
var23.setString(3, var2 == null ? "%" : var2);
var23.setString(4, var3 == null ? "%" : var3);
}
4解决办法
由封装的参数可知
1 ESCAPE 为 getTables(String var1, String var2, String var3, String[] var4) 方法中的var2参数
此处将var2参数传入指定用户即可。
追溯上游方法入参为:
public boolean isTablePresent(String tableName) 中的
String schema = dbSqlSession.getConnectionMetadataDefaultSchema();
修改 org.flowable.common.engine.impl.db.DbSqlSession 修改connectionMetadataDefaultSchema 属性即可
在此,本人在项目内重写一个AbstractSqlScriptBasedDbSchemaManager.java抽象类,将
String schema = dbSqlSession.getConnectionMetadataDefaultSchema(); 写死,重启项目生效
org/flowable/common/engine/impl/db/AbstractSqlScriptBasedDbSchemaManager.java
5还原
将新写的抽象方法注释掉,首次执行时打开,修改指定用户,启动