AnsweredAssumed Answered

HistoricFormProperty don't store the transformed value by the FormType

Question asked by mikedias on Mar 17, 2014
Latest reply on Mar 18, 2014 by mikedias
Hi,

Sometimes we need to store big variables in a process instance. Knowing that
ACT_RU_VARIABLE.TEXT_
is a VARCHAR(4000), we create a BinaryFormType to store the big string as a byte array. But, when history level is AUDIT, the engine tries to insert the unprocessed big value at
ACT_HI_DETAIL.TEXT_
, causing a <b>Value too long for column "TEXT_ VARCHAR(4000)"</b>.

Here is a test case that demonstrate the issue:

BPMN 2.0 file:

<?xml version='1.0' encoding='UTF-8'?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="binaryProcess" name="Binary Process" isExecutable="true">
    <startEvent id="sid-F9F0F672-8C03-4E1A-B5C0-C169B016E612">
      <extensionElements>
         <activiti:formProperty id="binaryProperty" name="binaryProperty" type="binary" />
      </extensionElements>
    </startEvent>
    <sequenceFlow id="sid-71C72183-6D1B-420B-96AB-476F10D7E905" sourceRef="sid-F9F0F672-8C03-4E1A-B5C0-C169B016E612" targetRef="sid-7CD47B08-8638-4A81-BC0C-89C2AC065684" />
    <userTask id="sid-7CD47B08-8638-4A81-BC0C-89C2AC065684" name="Binary Task">
      <extensionElements>
        <activiti:formProperty id="binaryProperty" name="binaryProperty" type="binary" />
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-56169958-5967-437D-8D1B-CFE42CDBDC5C" sourceRef="sid-7CD47B08-8638-4A81-BC0C-89C2AC065684" targetRef="sid-B3FF1567-3EC4-4053-BEF2-AC11883F0497" />
    <endEvent id="sid-B3FF1567-3EC4-4053-BEF2-AC11883F0497" />
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_binaryProcess">
    <bpmndi:BPMNPlane bpmnElement="binaryProcess" id="BPMNPlane_binaryProcess">
      <bpmndi:BPMNShape bpmnElement="sid-F9F0F672-8C03-4E1A-B5C0-C169B016E612" id="BPMNShape_sid-F9F0F672-8C03-4E1A-B5C0-C169B016E612">
        <omgdc:Bounds height="30.0" width="30.0" x="112.0" y="142.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-7CD47B08-8638-4A81-BC0C-89C2AC065684" id="BPMNShape_sid-7CD47B08-8638-4A81-BC0C-89C2AC065684">
        <omgdc:Bounds height="80.0" width="100.0" x="187.0" y="117.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-B3FF1567-3EC4-4053-BEF2-AC11883F0497" id="BPMNShape_sid-B3FF1567-3EC4-4053-BEF2-AC11883F0497">
        <omgdc:Bounds height="28.0" width="28.0" x="332.0" y="143.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-56169958-5967-437D-8D1B-CFE42CDBDC5C" id="BPMNEdge_sid-56169958-5967-437D-8D1B-CFE42CDBDC5C">
        <omgdi:waypoint x="287.0" y="157.0" />
        <omgdi:waypoint x="332.0" y="157.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-71C72183-6D1B-420B-96AB-476F10D7E905" id="BPMNEdge_sid-71C72183-6D1B-420B-96AB-476F10D7E905">
        <omgdi:waypoint x="142.0" y="157.0" />
        <omgdi:waypoint x="187.0" y="157.0" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

Test case:
[java]
package org.activiti.engine.test.history;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.form.AbstractFormType;
import org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
import org.activiti.engine.impl.history.HistoryLevel;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.junit.Test;

public class HistoricFormPropertyTest {
 
  public static final String BPMN_FILE_PATH = "org/activiti/engine/test/history/HistoricFormPropertyTest.binaryProperty.bpmn20.xml";
 
  public class BinaryFormType extends AbstractFormType {

    public String getName() {
      return "binary";
    }

    public Object convertFormValueToModelValue(String propertyValue) {
      return propertyValue.getBytes();
    }

    public String convertModelValueToFormValue(Object modelValue) {
      return new String((byte[])modelValue);
    }
   
  }
 
  public ProcessEngine buildProcessEngine(String historyLevel) {
    List<AbstractFormType> customFormTypes = new ArrayList<AbstractFormType>();
    customFormTypes.add(new BinaryFormType());
   
    StandaloneInMemProcessEngineConfiguration pec = new StandaloneInMemProcessEngineConfiguration();
    pec.setCustomFormTypes(customFormTypes);
    pec.setHistory(historyLevel);
    return pec.buildProcessEngine();
  }
 
  @Test
  public void testBigStringFormData() {
    //ProcessEngine pe = buildProcessEngine(HistoryLevel.NONE.getKey()); // works
    ProcessEngine pe = buildProcessEngine(HistoryLevel.AUDIT.getKey()); // fail
   
    Deployment d = pe.getRepositoryService().createDeployment().addClasspathResource(BPMN_FILE_PATH).deploy();
    ProcessDefinition pd = pe.getRepositoryService().createProcessDefinitionQuery().deploymentId(d.getId()).singleResult();
   
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10000; i++) {
      sb.append("big String… ");
    }
   
    Map<String, String> properties = new HashMap<String, String>();
    properties.put("binaryProperty", sb.toString());
   
    pe.getFormService().submitStartFormData(pd.getId(), properties);
   
    Task t = pe.getTaskService().createTaskQuery().singleResult();
   
    pe.getFormService().submitTaskFormData(t.getId(), properties);
   
  }
 
}
[/java]

My suggestion to solve this is:
  • Change the
    HistoricFormProperty
    to receive a Object instead of String;
  •  
  • Change the
    FormPropertyHandler.submitFormProperty
    to return the transformed value;
  •  
  • Change the
    SubmitTaskFormCmd
    and
    SubmitStartFormCmd
    to report form properties after form handler transformation.
What do you think? Can I do this fix or there are a better solution?

Outcomes