• 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

  • 相关阅读:
    Unity 3(一):简介与示例
    MongoDB以Windows Service运行
    动态SQL中变量赋值
    网站发布IIS后堆栈追踪无法获取出错的行号
    GridView Postback后出错Operation is not valid due to the current state of the object.
    Visual Studio 2010 SP1 在线安装后,找到缓存在本地的临时文件以便下次离线安装
    SQL Server 问题之 排序规则(collation)冲突
    IIS 问题集锦
    linux下安装mysql(ubuntu0.16.04.1)
    apt-get update 系列作用
  • 原文地址:https://www.cnblogs.com/rgqancy/p/7195810.html
Copyright © 2020-2023  润新知