
Activiti 手动部署 BPMN 文件时,仅生成 ge_bytearray 记录而未创建 re_procdef 中的流程定义,通常因重复部署名称导致部署被跳过;需确保每次部署使用唯一名称或清空历史部署。
activiti 手动部署 bpmn 流程时,仅生成 ge_bytearray 记录而未创建 re_procdef 中的流程定义,通常因重复部署名称导致部署被跳过;需确保每次部署使用唯一名称或清空历史部署。
在 Spring Boot + Activiti 环境中,从自动部署(如 spring.activiti.check-process-definitions=true)切换为手动 Java 部署时,一个常见却隐蔽的问题是:部署名称(deployment name)重复。Activiti 默认会对同名部署进行幂等处理——若已存在同名部署,它将跳过实际解析与流程定义注册,仅将 BPMN XML 写入 ge_bytearray 表(表现为 BYTES_ 字段中的 BLOB),而不会生成对应的 re_procdef 记录,导致后续无法启动流程实例。
你的代码逻辑本身基本正确(加载 BPMN、转换为 BpmnModel、调用 addBpmnModel()),但缺失了关键一步:显式设置唯一部署名称。Activiti 的 DeploymentBuilder 若未指定名称,会使用默认空字符串或内部生成的非唯一标识,极易触发重复部署判定。
✅ 正确做法是:每次部署必须使用唯一名称。推荐方式如下:
// ✅ 推荐:使用时间戳 + 随机后缀,确保全局唯一
String deploymentName = "process-deployment-" + System.currentTimeMillis() + "-" + UUID.randomUUID().toString().substring(0, 8);
DeploymentBuilder builder = repositoryService.createDeployment()
.name(deploymentName); // ← 关键:必须显式设置唯一 name!
// 后续保持原有逻辑(加载文件、转换模型、addBpmnModel...)
if (processDirectory.exists()) {
Arrays.stream(Objects.requireNonNull(processDirectory.list()))
.sequential()
.forEach(processDefFile -> {
try {
String resource = processFolderPath + processDefFile;
InputStream input = resourceLoader.getResource(resource).getInputStream();
InputStreamSource streamSource = new InputStreamSource(input);
BpmnModel model = bpmnXMLConverter.convertToBpmnModel(streamSource, true, false);
String processDefName = processDefFile.substring(0, processDefFile.indexOf(".bpmn20.xml"));
builder.addBpmnModel(processDefName, model);
} catch (IOException e) {
log.error("Failed to load or parse BPMN file: {}", processDefFile, e);
}
});
} else {
log.warn("Process directory not found: {}", processFolderPath);
}
builder.deploy(); // 现在 deploy() 将真正注册流程定义
⚠️ 注意事项:
-
不要依赖
spring.activiti.deployment-name配置项:该配置仅作用于自动部署阶段(SpringProcessEngineConfiguration初始化时),对运行时手动createDeployment()无效; -
避免手动清理数据库(如删除
act_re_deployment表记录):虽可临时解决,但破坏数据一致性且不可靠;应通过代码保证部署唯一性; -
验证部署结果:部署后建议添加断言或日志验证:
Deployment deployment = builder.deploy(); long procDefCount = repositoryService.createProcessDefinitionQuery() .deploymentId(deployment.getId()) .count(); log.info("Deployed {} process definitions under deployment ID: {}", procDefCount, deployment.getId()); - 若需热更新流程(开发期频繁重部署),可先删除旧部署(级联删除流程定义及资源):
repositoryService.deleteDeployment(deploymentId, true); // true = cascade
总结:Activiti 手动部署的核心原则是「显式命名 + 唯一性保障」。只要为每次 createDeployment() 显式赋予不重复的 name(),即可确保 BPMN 模型被正确解析、流程定义写入 re_procdef,并支持后续的启动、查询与执行。









