由于工作需要,需要将数据库变为国产数据库。导致activiti工作流不能使用。网上没找到类似解决方案,经过解决,记录总结方法如下。
activiti工作流支持的数据库
根据源码了解activiti工作流支持以下数据库。
一、工作流报错
配置好国产数据库,(这头不说如何配置了,百度都有)启动项目!
首次启动项目时候报如下错误。找不到名为KingbaseES的数据库
二、修改源码
因为activiti是开源的所以可以进行修改(不得不感叹开源真好)
修改的jar包为:acticiti-engin-5.16.4.jar
一共要修改jar包下这2个类。
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl
org.activiti.engine.impl.cfg.DbSqlSessionFactory
1、找到第一个类
使用Eclipse反编译工具打开这个类。
在src/main/java下创建一个和这个类路径一样的Package。
(1)如这个类是org.activiti.engine.impl.cfg。那么创建的Package名字也是这个。(为了修改后可以编译成class文件。因为其中引入了很多包,所以使用JVM的javac会编译失败)
(2)接下来创建一个与class一摸一样的java文件。
(3)复制class全文内容到java文件
(4)在public static final String DATABASE_TYPE_DB2 = “db2”;这句话下面新增一个数据库属性。(这里叫做kingbase)如下:
protected static Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
public static final String DATABASE_TYPE_H2 = "h2";
public static final String DATABASE_TYPE_MYSQL = "mysql";
public static final String DATABASE_TYPE_ORACLE = "oracle";
public static final String DATABASE_TYPE_POSTGRES = "postgres";
public static final String DATABASE_TYPE_MSSQL = "mssql";
public static final String DATABASE_TYPE_DB2 = "db2";
public static final String DATABASE_TYPE_KINGBASE = "kingbase";
(5)在protected static Properties getDefaultDatabaseTypeMappings()这个方法体里面加入一个setProperty。如下:
因为前面提醒activiti没有KingbaseES,所以我们创建一个这个。
protected static Properties getDefaultDatabaseTypeMappings() {
Properties databaseTypeMappings = new Properties();
databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
databaseTypeMappings.setProperty("PostgreSQL", DATABASE_TYPE_POSTGRES);
databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("KingbaseES", DATABASE_TYPE_KINGBASE);
return databaseTypeMappings;
}
2、找到第二个类
(1)与上面处理方法一样,创建一个一样的Package,然后创建一个一摸一样java文件。
(2)在static{}语句块中新增一段(其中注释kingbase下面就是我新增的)。
PS:因为我所使用的国产数据库与oracle类似,所以我将oracle粘贴了一份,将其中oracle修改成了kingbase,这里的kingbase字段,就是修改第一个类时候起的。
static {
String defaultOrderBy = " order by ${orderBy} ";
// h2
databaseSpecificLimitBeforeStatements.put("h2", "");
databaseSpecificLimitAfterStatements.put("h2", "LIMIT #{maxResults} OFFSET #{firstResult}");
databaseSpecificLimitBetweenStatements.put("h2", "");
databaseOuterJoinLimitBetweenStatements.put("h2", "");
databaseSpecificOrderByStatements.put("h2", defaultOrderBy);
// mysql specific
databaseSpecificLimitBeforeStatements.put("mysql", "");
databaseSpecificLimitAfterStatements.put("mysql", "LIMIT #{maxResults} OFFSET #{firstResult}");
databaseSpecificLimitBetweenStatements.put("mysql", "");
databaseOuterJoinLimitBetweenStatements.put("mysql", "");
databaseSpecificOrderByStatements.put("mysql", defaultOrderBy);
addDatabaseSpecificStatement("mysql", "selectProcessDefinitionsByQueryCriteria",
"selectProcessDefinitionsByQueryCriteria_mysql");
addDatabaseSpecificStatement("mysql", "selectProcessDefinitionCountByQueryCriteria",
"selectProcessDefinitionCountByQueryCriteria_mysql");
addDatabaseSpecificStatement("mysql", "selectDeploymentsByQueryCriteria",
"selectDeploymentsByQueryCriteria_mysql");
addDatabaseSpecificStatement("mysql", "selectDeploymentCountByQueryCriteria",
"selectDeploymentCountByQueryCriteria_mysql");
addDatabaseSpecificStatement("mysql", "selectModelCountByQueryCriteria",
"selectModelCountByQueryCriteria_mysql");
addDatabaseSpecificStatement("mysql", "updateExecutionTenantIdForDeployment",
"updateExecutionTenantIdForDeployment_mysql");
addDatabaseSpecificStatement("mysql", "updateTaskTenantIdForDeployment",
"updateTaskTenantIdForDeployment_mysql");
addDatabaseSpecificStatement("mysql", "updateJobTenantIdForDeployment", "updateJobTenantIdForDeployment_mysql");
// postgres specific
databaseSpecificLimitBeforeStatements.put("postgres", "");
databaseSpecificLimitAfterStatements.put("postgres", "LIMIT #{maxResults} OFFSET #{firstResult}");
databaseSpecificLimitBetweenStatements.put("postgres", "");
databaseOuterJoinLimitBetweenStatements.put("postgres", "");
databaseSpecificOrderByStatements.put("postgres", defaultOrderBy);
addDatabaseSpecificStatement("postgres", "insertByteArray", "insertByteArray_postgres");
addDatabaseSpecificStatement("postgres", "updateByteArray", "updateByteArray_postgres");
addDatabaseSpecificStatement("postgres", "selectByteArray", "selectByteArray_postgres");
addDatabaseSpecificStatement("postgres", "selectResourceByDeploymentIdAndResourceName",
"selectResourceByDeploymentIdAndResourceName_postgres");
addDatabaseSpecificStatement("postgres", "selectResourcesByDeploymentId",
"selectResourcesByDeploymentId_postgres");
addDatabaseSpecificStatement("postgres", "insertIdentityInfo", "insertIdentityInfo_postgres");
addDatabaseSpecificStatement("postgres", "updateIdentityInfo", "updateIdentityInfo_postgres");
addDatabaseSpecificStatement("postgres", "selectIdentityInfoById", "selectIdentityInfoById_postgres");
addDatabaseSpecificStatement("postgres", "selectIdentityInfoByUserIdAndKey",
"selectIdentityInfoByUserIdAndKey_postgres");
addDatabaseSpecificStatement("postgres", "selectIdentityInfoByUserId", "selectIdentityInfoByUserId_postgres");
addDatabaseSpecificStatement("postgres", "selectIdentityInfoDetails", "selectIdentityInfoDetails_postgres");
addDatabaseSpecificStatement("postgres", "insertComment", "insertComment_postgres");
addDatabaseSpecificStatement("postgres", "selectComment", "selectComment_postgres");
addDatabaseSpecificStatement("postgres", "selectCommentsByTaskId", "selectCommentsByTaskId_postgres");
addDatabaseSpecificStatement("postgres", "selectCommentsByProcessInstanceId",
"selectCommentsByProcessInstanceId_postgres");
addDatabaseSpecificStatement("postgres", "selectCommentsByProcessInstanceIdAndType",
"selectCommentsByProcessInstanceIdAndType_postgres");
addDatabaseSpecificStatement("postgres", "selectCommentsByType", "selectCommentsByType_postgres");
addDatabaseSpecificStatement("postgres", "selectCommentsByTaskIdAndType",
"selectCommentsByTaskIdAndType_postgres");
addDatabaseSpecificStatement("postgres", "selectEventsByTaskId", "selectEventsByTaskId_postgres");
addDatabaseSpecificStatement("postgres", "insertEventLogEntry", "insertEventLogEntry_postgres");
addDatabaseSpecificStatement("postgres", "selectAllEventLogEntries", "selectAllEventLogEntries_postgres");
addDatabaseSpecificStatement("postgres", "selectEventLogEntries", "selectEventLogEntries_postgres");
addDatabaseSpecificStatement("postgres", "selectEventLogEntriesByProcessInstanceId",
"selectEventLogEntriesByProcessInstanceId_postgres");
// oracle
databaseSpecificLimitBeforeStatements.put("oracle", "select * from ( select a.*, ROWNUM rnum from (");
databaseSpecificLimitAfterStatements.put("oracle",
" ) a where ROWNUM < #{lastRow}) where rnum >= #{firstRow}");
databaseSpecificLimitBetweenStatements.put("oracle", "");
databaseOuterJoinLimitBetweenStatements.put("oracle", "");
databaseSpecificOrderByStatements.put("oracle", defaultOrderBy);
addDatabaseSpecificStatement("oracle", "selectExclusiveJobsToExecute",
"selectExclusiveJobsToExecute_integerBoolean");
addDatabaseSpecificStatement("oracle", "selectUnlockedTimersByDuedate", "selectUnlockedTimersByDuedate_oracle");
addDatabaseSpecificStatement("oracle", "insertEventLogEntry", "insertEventLogEntry_oracle");
// kingbase
databaseSpecificLimitBeforeStatements.put("kingbase", "select * from ( select a.*, ROWNUM rnum from (");
databaseSpecificLimitAfterStatements.put("kingbase",
" ) a where ROWNUM < #{lastRow}) where rnum >= #{firstRow}");
databaseSpecificLimitBetweenStatements.put("kingbase", "");
databaseOuterJoinLimitBetweenStatements.put("kingbase", "");
databaseSpecificOrderByStatements.put("kingbase", defaultOrderBy);
addDatabaseSpecificStatement("kingbase", "selectExclusiveJobsToExecute",
"selectExclusiveJobsToExecute_integerBoolean");
addDatabaseSpecificStatement("kingbase", "selectUnlockedTimersByDuedate",
"selectUnlockedTimersByDuedate_oracle");
addDatabaseSpecificStatement("kingbase", "insertEventLogEntry", "insertEventLogEntry_oracle");
// db2
databaseSpecificLimitBeforeStatements.put("db2", "SELECT SUB.* FROM (");
databaseSpecificLimitAfterStatements.put("db2",
")RES ) SUB WHERE SUB.rnk >= #{firstRow} AND SUB.rnk < #{lastRow}");
databaseSpecificLimitBetweenStatements.put("db2",
", row_number() over (ORDER BY ${orderBy}) rnk FROM ( select distinct RES.* ");
databaseOuterJoinLimitBetweenStatements.put("db2",
", row_number() over (ORDER BY ${mssqlOrDB2OrderBy}) rnk FROM ( select distinct ");
databaseSpecificOrderByStatements.put("db2", "");
databaseSpecificLimitBeforeNativeQueryStatements.put("db2",
"SELECT SUB.* FROM ( select RES.* , row_number() over (ORDER BY ${orderBy}) rnk FROM (");
addDatabaseSpecificStatement("db2", "selectExclusiveJobsToExecute",
"selectExclusiveJobsToExecute_integerBoolean");
addDatabaseSpecificStatement("db2", "selectExecutionByNativeQuery",
"selectExecutionByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectHistoricActivityInstanceByNativeQuery",
"selectHistoricActivityInstanceByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectHistoricProcessInstanceByNativeQuery",
"selectHistoricProcessInstanceByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectHistoricTaskInstanceByNativeQuery",
"selectHistoricTaskInstanceByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectTaskByNativeQuery", "selectTaskByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectProcessDefinitionByNativeQuery",
"selectProcessDefinitionByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectDeploymentByNativeQuery",
"selectDeploymentByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectGroupByNativeQuery", "selectGroupByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectUserByNativeQuery", "selectUserByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectModelByNativeQuery", "selectModelByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectHistoricDetailByNativeQuery",
"selectHistoricDetailByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectHistoricVariableInstanceByNativeQuery",
"selectHistoricVariableInstanceByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectTaskWithVariablesByQueryCriteria",
"selectTaskWithVariablesByQueryCriteria_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectProcessInstanceWithVariablesByQueryCriteria",
"selectProcessInstanceWithVariablesByQueryCriteria_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectHistoricProcessInstancesWithVariablesByQueryCriteria",
"selectHistoricProcessInstancesWithVariablesByQueryCriteria_mssql_or_db2");
addDatabaseSpecificStatement("db2", "selectHistoricTaskInstancesWithVariablesByQueryCriteria",
"selectHistoricTaskInstancesWithVariablesByQueryCriteria_mssql_or_db2");
// mssql
databaseSpecificLimitBeforeStatements.put("mssql", "SELECT SUB.* FROM (");
databaseSpecificLimitAfterStatements.put("mssql",
")RES ) SUB WHERE SUB.rnk >= #{firstRow} AND SUB.rnk < #{lastRow}");
databaseSpecificLimitBetweenStatements.put("mssql",
", row_number() over (ORDER BY ${orderBy}) rnk FROM ( select distinct RES.* ");
databaseOuterJoinLimitBetweenStatements.put("mssql",
", row_number() over (ORDER BY ${mssqlOrDB2OrderBy}) rnk FROM ( select distinct ");
databaseSpecificOrderByStatements.put("mssql", "");
databaseSpecificLimitBeforeNativeQueryStatements.put("mssql",
"SELECT SUB.* FROM ( select RES.* , row_number() over (ORDER BY ${orderBy}) rnk FROM (");
addDatabaseSpecificStatement("mssql", "selectExclusiveJobsToExecute",
"selectExclusiveJobsToExecute_integerBoolean");
addDatabaseSpecificStatement("mssql", "selectExecutionByNativeQuery",
"selectExecutionByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectHistoricActivityInstanceByNativeQuery",
"selectHistoricActivityInstanceByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectHistoricProcessInstanceByNativeQuery",
"selectHistoricProcessInstanceByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectHistoricTaskInstanceByNativeQuery",
"selectHistoricTaskInstanceByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectTaskByNativeQuery", "selectTaskByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectProcessDefinitionByNativeQuery",
"selectProcessDefinitionByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectDeploymentByNativeQuery",
"selectDeploymentByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectGroupByNativeQuery", "selectGroupByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectUserByNativeQuery", "selectUserByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectModelByNativeQuery", "selectModelByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectHistoricDetailByNativeQuery",
"selectHistoricDetailByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectHistoricVariableInstanceByNativeQuery",
"selectHistoricVariableInstanceByNativeQuery_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectTaskWithVariablesByQueryCriteria",
"selectTaskWithVariablesByQueryCriteria_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectProcessInstanceWithVariablesByQueryCriteria",
"selectProcessInstanceWithVariablesByQueryCriteria_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectHistoricProcessInstancesWithVariablesByQueryCriteria",
"selectHistoricProcessInstancesWithVariablesByQueryCriteria_mssql_or_db2");
addDatabaseSpecificStatement("mssql", "selectHistoricTaskInstancesWithVariablesByQueryCriteria",
"selectHistoricTaskInstancesWithVariablesByQueryCriteria_mssql_or_db2");
}
三、重新生成jar包。
(1)找到项目路径下存放class文件的位置。我这里是/target/classes/下。
(2)将之前修改的两个类class文件取出。
(3)我是使用maven引入的工作流jar包,所以去maven的本地仓库找到这个jar包。
路径可以在jar包后面查看。
(4)找到路径打开后是这样的
activiti-engine-5.16.4.jar(JVM所使用的包,其中都是class文件)
activiti-engine-5.16.4-sources.jar(里面是源码,其中都是java文件,也是Eclipse查看的)
其中activiti-engine-5.16.4.jar必须修改,不然没法用。
(5)将activiti-engine-5.16.4.jar复制一份后解压
根据前面两个类的路径找到原有class文件,将之前修改好取出的class文件用来替换。
这两个类
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl
org.activiti.engine.impl.cfg.DbSqlSessionFactory
(6)在下面这个位置将两个文件夹压缩
(7)修改名字及后缀为activiti-engine-5.16.4.jar
(8)这个activiti-engine-5.16.4-sources.jar包与上面的修改方法一样,不过里面是java文件。可以使用之前Eclipse项目中java文件进行替换。
四、替换jar包。
(1)与maven仓库中的jar包进行替换。
(2)项目点击右键->Maven->Update Project。重新加载jar包。
(3)启动项目成功。或者修复好之前错误。