springboot集成flowable遇到的问题
1.解决报错:Cause: java.sql.SQLSyntaxErrorException: Table ‘*.act_ge_property’ doesn’t exist
原因
由于mysql版本问题,mysql8.xxx以上驱动会出现这个问题,下图是我原mysql配置,是8.0+。
因为mysql使用schema标识库名而不是catalog,因此mysql会扫描所有的库来找表,如果其他库中有相同名称的表,activiti就以为找到了,本质上这个表在当前数据库中并不存在。
设置nullCatalogMeansCurrent=true,表示mysql默认当前数据库操作,在mysql-connector-java 5.xxx该参数默认为true,在6.xxx以上默认为false,因此需要设置nullCatalogMeansCurrent=true
。
解决办法
在连接驱动中增加配置:
url: jdbc:mysql://localhost:3306/demo2?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true
&serverTimezone=UTC
2. mybatis版本问题
由于项目里面的springboot版本和flowable-proccess-starter的版本不匹配的问题,项目启动时,可能会遇到如下报错
Error creating bean with name 'processEngine': FactoryBean threw exception on object creation; nested exception is java.lang.NoClassDefFoundError: org/apache/ibatis/type/SqlxmlTypeHandler
..
...
Caused by: java.lang.NoClassDefFoundError: org/apache/ibatis/type/SqlxmlTypeHandler
at org.flowable.common.engine.impl.AbstractEngineConfiguration.initMybatisTypeHandlers(AbstractEngineConfiguration.java:954)
at org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl.initMybatisTypeHandlers(ProcessEngineConfigurationImpl.java:1168)
at org.flowable.common.engine.impl.AbstractEngineConfiguration.initMybatisConfiguration(AbstractEngineConfiguration.java:891)
at org.flowable.common.engine.impl.AbstractEngineConfiguration.initSqlSessionFactory(AbstractEngineConfiguration.java:862)
at org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl.init(ProcessEngineConfigurationImpl.java:988)
at org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl.buildProcessEngine(ProcessEngineConfigurationImpl.java:906)
at org.flowable.spring.SpringProcessEngineConfiguration.buildProcessEngine(SpringProcessEngineConfiguration.java:76)
at org.flowable.spring.ProcessEngineFactoryBean.getObject(ProcessEngineFactoryBean.java:59)
at org.flowable.spring.ProcessEngineFactoryBean.getObject(ProcessEngineFactoryBean.java:32)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:169)
... 91 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.apache.ibatis.type.SqlxmlTypeHandler
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 101 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:58693', transport: 'socket'
Process finished with exit code 1
解决方法:
- 降低flowable版本(这种方式是一种尝试的方式,如果降到mybatis 3.4.6版本时,flowable需使用2018年的版本,相关功能会打折扣,也会暴露出老版本的一些bug,建议不采用)
- 升级mybatis版本(flowable 6.8 对应的mybatis版本是3.5.5,则升级到这个版本)
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
但升级后可能会导致原系统中dao层的一些代码出现问题,需要进行功能回归,避免给系统带了未知问题。
3. 业务表和工作流的表字段进行sql比较时报错:Illegal mix of collations (utf8_bin ,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT)
原因
由于flowable的表是自动生成的,项目默认的mysql数据库编码是,字符集:utf8mb4
;排序规则:utf8mb4_general_ci
。但 flowable自动生成的表的 字符集是:utf8
;排序规则:utf8_bin
。在执行sql语句,做关联表查询有时候会报错,字段的排序规则不一样。
类别 | 字符集 | 排序规则 |
flowable自动生成的表 | utf8 | utf8_bin |
业务表 | utf8mb4 | utf8mb4_general_ci |
解决办法
统一数据库的字符集和排序规则。
-- 查看数据库中的字符集
show variables where Variable_name like '%collation%'
-- 查看某个数据库的表的用的字符集
SELECT TABLE_SCHEMA '数据库',TABLE_NAME '表',TABLE_COLLATION '原排序规则',CONCAT('ALTER TABLE ',TABLE_NAME, ' CHARACTER SET=utf8mb4, COLLATE=utf8mb4_general_ci;') '修正SQL'
FROM information_schema.`TABLES` where TABLE_SCHEMA = '你的数据库名' and TABLE_COLLATION != 'utf8mb4_general_ci'
-- 查看数据库中所有字段用的排序规则
SELECT
TABLE_SCHEMA '数据库',
TABLE_NAME '表',
COLUMN_NAME '字段',
CHARACTER_SET_NAME '原字符集',
COLLATION_NAME '原排序规则',
CONCAT(
'ALTER TABLE ',
TABLE_NAME,
' MODIFY COLUMN ',
COLUMN_NAME,
' ',
COLUMN_TYPE,
-- - 设置新的编码和排序规则
' CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci',
( CASE WHEN IS_NULLABLE = 'NO' THEN ' NOT NULL' ELSE '' END ),
( CASE WHEN COLUMN_COMMENT = '' THEN ' ' ELSE concat( ' COMMENT''', COLUMN_COMMENT, '''' ) END ),
';'
) '修正SQL'
FROM
information_schema.`COLUMNS`
WHERE
-- -过滤正确排序规则
COLLATION_NAME != 'utf8mb4_general_ci'
-- -数据库名称
AND TABLE_SCHEMA = '你的数据库名';
3. flowable在执行serviceTask任务类型时(异步执行),由于业务方法异常导致事务回滚(设置 边界异常捕获未生效)
4. flowable内置的工具类无法正常使用
比如:要使用 org.flowable.engine.impl.util.ProcessDefinitionUtil.getProcess(processDefinitionId)的方法,会报错Cannot get process model: no current command context is active
。
查看源码,是下面的第2行context为空导致的。
public static Process getProcess(String processDefinitionId) {
if (Context.getCommandContext() == null) {
throw new FlowableException("Cannot get process model: no current command context is active");
} else if (CommandContextUtil.getProcessEngineConfiguration() == null) {
return Flowable5Util.getFlowable5CompatibilityHandler().getProcessDefinitionProcessObject(processDefinitionId);
} else {
DeploymentManager deploymentManager = CommandContextUtil.getProcessEngineConfiguration().getDeploymentManager();
// This will check the cache in the findDeployedProcessDefinitionById and resolveProcessDefinition method
ProcessDefinition processDefinitionEntity = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);
return deploymentManager.resolveProcessDefinition(processDefinitionEntity).getProcess();
}
}
进一步分析,是这个拦截器org.flowable.common.engine.impl.interceptor.CommandContextInterceptor
在负责context。
而触发这个拦截器,需要通过 org.flowable.engine.ManagementService#executeCommand(org.flowable.common.engine.impl.interceptor.Command<T>)
的方法来触发。
也就是说 flowable内置的util,大多数只能通过flowable的管理器来调用。我们可以通过封装 cmd的方法来使用内置的flowable util。