公司做的项目要求去ioe使用国产的替代方案,考虑flowable社区比较活跃,使用flowable工作流引擎做适配。数据从异构数据库中迁移到OSCAR神通数据库,应用中使用flowable工作流在替换了数据库驱动后启动过程报错如下:
nested exception is org.activiti.engine.ActivitiException: couldn't deduct database type from database product name 'OSCAR'
原因是:flowable6.8.0内置的数据库类型不支持神通数据库.
解决方案一:
将flowable.engine.common相关源码拷贝到工程src下,保持包路径不变,并做相应修改以支持神通数据库,源码地址
https://github.com/flowable/flowable-engine/releases
注意要对应版本,各版本数据库有差异
具体如下:
1、在package org.flowable.common.engine.impl,AbstractEngineConfiguration增加成员变量224行左右
public static final String DATABASE_TYPE_OSCAR = "oscar";
public static final String DATABASE_TYPE_H2 = "h2";
public static final String DATABASE_TYPE_HSQL = "hsql";
public static final String DATABASE_TYPE_MYSQL = "mysql";
public static final String DATABASE_TYPE_ORACLE = "oracle";
2、在package org.flowable.common.engine.impl,AbstractEngineConfiguration修改
getDefaultDatabaseTypeMappings()在248行左右
protected static Properties getDefaultDatabaseTypeMappings() {
Properties databaseTypeMappings = new Properties();
databaseTypeMappings.setProperty("OSCAR ", DATABASE_TYPE_OSCAR );
databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
3、在org.flowable.common.engine.impl.db;152行,DbSqlSessionFactory修改
initBulkInsertEnabledMap(String
databaseType)
if ("oracle".equals(databaseType) || "oscar".equals(databaseType)) {
bulkInsertableMap.put(EventLogEntryEntity.class, Boolean.FALSE);
4、在org.flowable.common.db.properties创建oscar.properties新建 oscar.properties
limitBefore=
limitAfter=LIMIT #{maxResults} OFFSET #{firstResult}
5、在package org.flowable.common.engine.impl.db在ListQueryParameterObject
文件,修改addOrder(String column, String sortOrder。
NullHandlingOnOrder nullHandlingOnOrder)
if (nullHandlingOnOrder.equals(NullHandlingOnOrder.NULLS_FIRST)) {
if (ProcessEngineConfigurationImpl.DATABASE_TYPE_H2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_HSQL.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_POSTGRES.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_ORACLE.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_OSCAR.equals(databaseType)) {
orderBy = orderBy + defaultOrderByClause + " NULLS FIRST";
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL.equals(databaseType)) {
orderBy = orderBy + "isnull(" + column + ") desc," + defaultOrderByClause;
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_DB2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_MSSQL.equals(databaseType)) {
orderBy = orderBy + "case when " + column + " is null then 0 else 1 end," + defaultOrderByClause;
} else {
orderBy = orderBy + defaultOrderByClause;
}
} else if (nullHandlingOnOrder.equals(NullHandlingOnOrder.NULLS_LAST)) {
if (ProcessEngineConfigurationImpl.DATABASE_TYPE_H2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_HSQL.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_POSTGRES.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_ORACLE.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_OSCAR.equals(databaseType)) {
orderBy = orderBy + column + " " + sortOrder + " NULLS LAST";
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL.equals(databaseType)) {
orderBy = orderBy + "isnull(" + column + ") asc," + defaultOrderByClause;
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_DB2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_MSSQL.equals(databaseType)) {
orderBy = orderBy + "case when " + column + " is null then 1 else 0 end," + defaultOrderByClause;
} else {
orderBy = orderBy + defaultOrderByClause;
}
}
解决方案二:
方案一是为正道但bug重重,除了以上方案还有一个取巧方案:
1、关闭flowable自动建表
2、将方案一中一二三步配置成pgsql或oracle
3、找到源码中pgsql建表语句在神通数据库上执行。
完美解决。