Issue: business key in a call activiti
https://community.alfresco.com/thread/221280-business-key-in-a-call-activity
这个帖子有一些讨论和回复。
https://community.alfresco.com/thread/218788-call-activity-and-businesskey#
这个帖子一直没人回答。
https://stackoverflow.com/questions/26497569/activity-how-to-know-if-an-execution-is-linked-to-an-instance-of-subprocess
https://community.alfresco.com/thread/221348-get-all-active-tasks-including-sub-process-tasks
这篇文章比较中肯,社区分享了两种(潜在的)WorkAround的方案,详见下边解决方案部分。
http://blog.csdn.net/lovemenghaibin/article/details/50608300
这个帖子是讲business key的用户的入门文章,和本问题无关。
act_ru_execution表的BUSINESS_KEY_ 字段,在使用call activiti时,子流程的BUSINESS_KEY_会丢失,而不能从父流程继承过来。
解决方案:
1.《Activiti权威指南》作者冀正,给的建议的解决办法:修改源代码,一行代码就能把丢失的BUSINESS_KEY_拷贝过来。
2.用ExecutionListener或者ActivitiEventListener监听CallActiviti的创建过程,然后把父流程实例的Business存入流程变量中。
社区网友由ExecutionListener到ActivitiEventListener逐步讨论。
a) ExecutionListener
/** * BusinessKeyInjectionListener.java * com.yuanchuangyun.workflow.listener * * Function: TODO * * ver date author * ────────────────────────────────── * 2017年12月1日 renguoqiang * * Copyright (c) 2017, yuanchuangyun All Rights Reserved. */ package com.yuanchuangyun.workflow.listener; import org.activiti.engine.delegate.DelegateExecution; import org.activiti.engine.delegate.ExecutionListener; import org.activiti.engine.impl.persistence.entity.ExecutionEntity; /** * ClassName:BusinessKeyInjectionExecutionListener * @author renguoqiang * @version * @since Ver 1.1 * @Date 2017年12月1日 下午4:10:37 * * @see */ public class BusinessKeyInjectionExecutionListener implements ExecutionListener{ /** * serialVersionUID:TODO(用一句话描述这个变量表示什么) * * @since Ver 1.1 */ private static final long serialVersionUID = 1L; @Override public void notify(DelegateExecution exec) throws Exception { System.out.println("In BusinessKey Injection Listener"); ExecutionEntity thisEntity = (ExecutionEntity)exec; ExecutionEntity superExecEntity = thisEntity.getSuperExecution(); String key = ""; // Check if this is the main process. if( superExecEntity == null ){ // If it is, get the business key the main process was launched with. key = thisEntity.getBusinessKey(); }else{ // We are a subprocess so get the BusinessKey variable set by the caller. // This should work for N level deep sub processes. key = (String)superExecEntity.getVariable("BusinessKey"); } // Set a process variable with the business key. Can't actually set business key because business keys // have to be unique per process instance. thisEntity.setVariable("BusinessKey", key); } }
b) ActivitiEventListener
/** * BusinessKeyInjectionActivitiEventListener.java * com.yuanchuangyun.workflow.listener * * Function: TODO * * ver date author * ────────────────────────────────── * 2017年12月1日 renguoqiang * * Copyright (c) 2017, yuanchuangyun All Rights Reserved. */ package com.yuanchuangyun.workflow.listener; import org.activiti.engine.delegate.event.ActivitiEntityEvent; import org.activiti.engine.delegate.event.ActivitiEvent; import org.activiti.engine.delegate.event.ActivitiEventListener; import org.activiti.engine.impl.persistence.entity.ExecutionEntity; import org.activiti.engine.impl.persistence.entity.TaskEntity; /** * ClassName:BusinessKeyInjectionActivitiEventListener * @author renguoqiang * @version * @since Ver 1.1 * @Date 2017年12月1日 下午5:03:29 * * @see */ public class BusinessKeyInjectionActivitiEventListener implements ActivitiEventListener { private String getSuperProcessInstanceId(ExecutionEntity exEntity) { if (exEntity != null && exEntity.getSuperExecution() != null) { return getSuperProcessInstanceId(exEntity.getSuperExecution()); } else if (exEntity != null) { return exEntity.getProcessInstanceId(); } return null; } @Override public void onEvent(ActivitiEvent event) { switch (event.getType()) { case TASK_CREATED: if (event instanceof ActivitiEntityEvent) { ActivitiEntityEvent activityEntityEvent = (ActivitiEntityEvent) event; TaskEntity taskEntity = (TaskEntity) activityEntityEvent .getEntity(); ExecutionEntity exEntity = taskEntity.getExecution(); String superExId = getSuperProcessInstanceId(exEntity != null ? exEntity .getSuperExecution() : null); if (superExId != null) { taskEntity.setAssignee(superExId); } try { @SuppressWarnings("null") ExecutionEntity executionEntity = (ExecutionEntity) activityEntityEvent .getEntity(); ExecutionEntity superExecEntity = executionEntity .getSuperExecution(); String key = ""; // Check if this is the main process. if (superExecEntity == null) { // key = executionEntity.getBusinessKey(); key = (String) executionEntity .getVariable("BusinessKey"); } else { key = (String) superExecEntity .getVariable("BusinessKey"); } executionEntity.setVariable("BusinessKey", key); } catch (Exception e) { // System.out.println("ENTITY CAST ERROR !!!!!!!!"); } break; // ... } default: break; } } @Override public boolean isFailOnException() { // TODO Auto-generated method stub return false; } }
TIP:从Activiti的官方文档,可知BusinessKey这个列,预留只是为了兼容一些历史问题。系统设计时,应该避免使用此值,这样Activiti就更独立一下(耦合小),也就是把业务的主键与ProcessInstanceId的关联记录,放入自定义的业务表中存储。
源码附件:https://files.cnblogs.com/files/rgqancy/BusinessKey.zip
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具