zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    [JavaEE] Hibernate连接池配置测试
    restful--参考文档
    webapi--参考文档
    注册中心--参考文档
    .NET Core中文智能辅助提示设置
    .NET Core+web服务器在本地机房用几台电脑实现负载均衡+集群
    调式、跟踪
    微服务架构:介绍、分布式与集群、架构四要素、设计模式、架构说明、项目结构说明、通讯方式、架构演进
    异步:Task、Async、await、委托异步(Invoke、BeginInvoke、EndInvoke)
    IO使用解析
  • 原文地址:https://www.cnblogs.com/rgqancy/p/7195810.html
Copyright © 2011-2022 走看看