Activiti6报TransientVariableInstance强转VariableInstanceEntity异常
Activiti6 设置瞬态变量触发ClassCastException问题
问题场景
使用Activiti6版本搭建仅包含ServiceTask节点的工作流,在节点执行逻辑中设置瞬态变量,工作流全部执行完成后,Activiti框架内部抛出类型转换异常。
问题复现代码(自定义JavaDelegate实现类中设置瞬态变量):
public class TestDispatcher implements JavaDelegate { @Override public void execute(DelegateExecution execution) { execution.setTransientVariable("test", "123"); } }
报错详情
报错触发位置为ExecutionEntityManagerImpl类第569行,该段代码逻辑为获取执行实例关联的变量并执行删除操作,对应源码如下:
if (!enableExecutionRelationshipCounts || (enableExecutionRelationshipCounts && ((CountingExecutionEntity) executionEntity).getVariableCount() > 0)) { Collection<VariableInstance> executionVariables = executionEntity.getVariableInstancesLocal().values(); for (VariableInstance variableInstance : executionVariables) { VariableInstanceEntity variableInstanceEntity = (VariableInstanceEntity) variableInstance; VariableInstanceEntityManager variableInstanceEntityManager = getVariableInstanceEntityManager(); variableInstanceEntityManager.delete(variableInstanceEntity); if (variableInstanceEntity.getByteArrayRef() != null && variableInstanceEntity.getByteArrayRef().getId() != null) { getByteArrayEntityManager().deleteByteArrayById(variableInstanceEntity.getByteArrayRef().getId()); } } }
抛出的具体异常信息:java.lang.ClassCastException: org.activiti.engine.impl.persistence.entity.TransientVariableInstance cannot be cast to org.activiti.engine.impl.persistence.entity.VariableInstanceEntity
问题根因
Activiti6流程结束清理变量时,getVariableInstancesLocal()接口返回的变量集合同时包含持久化变量和瞬态变量:
- 持久化变量对应的实现类是
VariableInstanceEntity,需要执行数据库层面的删除逻辑 - 瞬态变量对应的实现类是
TransientVariableInstance,本身不持久化到数据库,不需要走删除流程
但源码遍历变量集合时未做类型区分,直接将所有元素强转为VariableInstanceEntity,遇到瞬态变量时就会触发类型转换异常。
解决方法
- 无侵入临时规避:在ServiceTask的业务逻辑执行完成前,主动移除当前设置的瞬态变量,保证流程进入变量清理逻辑时,执行实例下无残留瞬态变量。示例:
@Override public void execute(DelegateExecution execution) { execution.setTransientVariable("test", "123"); // 业务逻辑处理完成后主动移除瞬态变量 execution.removeTransientVariable("test"); } - 源码层彻底修复:修改变量清理逻辑,遍历变量时增加类型判断,仅对持久化类型的变量执行删除操作,瞬态变量直接跳过。核心修改点为遍历循环内增加类型校验:
for (VariableInstance variableInstance : executionVariables) { // 跳过非持久化的瞬态变量 if (!(variableInstance instanceof VariableInstanceEntity)) { continue; } VariableInstanceEntity variableInstanceEntity = (VariableInstanceEntity) variableInstance; // 后续原有删除逻辑保持不变 // ... }
内容的提问来源于stack exchange,提问作者Groovvy
相关产品推荐
相关产品推荐

