[jboss-jira] [JBoss JIRA] Created: (JBPM-757) Constraint violation during process deletion

Dave Caruana (JIRA) jira-events at jboss.com
Tue Sep 26 09:07:01 EDT 2006


Constraint violation during process deletion
--------------------------------------------

                 Key: JBPM-757
                 URL: http://jira.jboss.com/jira/browse/JBPM-757
             Project: JBoss jBPM
          Issue Type: Bug
          Components: Core Engine
    Affects Versions:  jBPM 3.1.2
         Environment: Windows XP, Java 5, MySQL & HSQL.
            Reporter: Dave Caruana
         Assigned To: Tom Baeyens


It's taken a while to pinpoint the exact use-case, however the following test case reproduces the issue.  I don't believe I'm incorrectly using jPDL.

The process has a start task with a task controller that writes a variable (named var1) back to the process.  Note, the process does not have var1 to start with.  Then, a local variable 'var1' is set on the start task instance and the task is ended.  

Please note, at this point, there are VariableInstances persisted without an associated token, tokenvarmap, taskinstance or processinstance.   That's potentially another side-issue, but not core to this particular deletion issue.

The second task 'step2Task' is created (no task controller associated with it).  Now, a new local variable 'var1' is set against this task instance.  The task is ended.

At this point, the process is deleted.  However, it fails with a constraint violation (from FK_VARINST_TKVARMP, in the table "JBPM_VARIABLEINSTANCE" reported in MySQL) or a general exception (reported in HSQL).

Some digging reveals that when the step2Task task instance is ended, all local variables are pushed back to the process.  However, the process already has a var1 as written explicitly by the task controller of the start task.  It seems in TaskInstance.submitVariables, the process var1 is not deleted before the task local variable replaces process variable in the process token variable map.

The following test case demonstrates the issue with the default jbpm configuration files.

import java.util.List;

import junit.framework.TestCase;

import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.db.GraphSession;
import org.jbpm.db.TaskMgmtSession;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.jbpm.taskmgmt.exe.TaskInstance;


public class JBPMDeleteProcessTest extends TestCase {

    static JbpmConfiguration jbpmConfiguration = null; 
    static long processId = -1L;
    static String currentTokenPath = null;

    static {
      jbpmConfiguration = JbpmConfiguration.parseXmlString(
        "<jbpm-configuration>" +
        "  <jbpm-context>" +
        "    <service name='persistence' " +
        "             factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />" + 
        "  </jbpm-context>" +
        "  <string name='resource.hibernate.cfg.xml' " +
        "          value='hibernate.cfg.xml' />" +
        "  <string name='resource.business.calendar' " +
        "          value='org/jbpm/calendar/jbpm.business.calendar.properties' />" +
        "  <string name='resource.default.modules' " +
        "          value='org/jbpm/graph/def/jbpm.default.modules.properties' />" +
        "  <string name='resource.converter' " +
        "          value='org/jbpm/db/hibernate/jbpm.converter.properties' />" +
        "  <string name='resource.action.types' " +
        "          value='org/jbpm/graph/action/action.types.xml' />" +
        "  <string name='resource.node.types' " +
        "          value='org/jbpm/graph/node/node.types.xml' />" +
        "  <string name='resource.varmapping' " +
        "          value='org/jbpm/context/exe/jbpm.varmapping.xml' />" +
        "</jbpm-configuration>"
      );
    }
    
    public void setUp() {
      jbpmConfiguration.createSchema();
    }
    
    public void tearDown() {
      jbpmConfiguration.dropSchema();
    }

    public void testDelete() {
      deployProcessDefinition();

      startProcess();
      step2TaskEnd();
      deleteProcess();
    }

    public void deployProcessDefinition() {
      ProcessDefinition processDefinition = ProcessDefinition.parseXmlString
      (
        "<process-definition name='deletetest'>" +
        "  <start-state name='start'> " +  
        "    <task name='startTask'> " +
        "      <controller> " +
        "        <variable name='var1' access='write'/> " +
        "      </controller> " +
        "    </task> " +
        "   <transition name='' to='step2'/> " +
        "  </start-state> " +
        "  <task-node name='step2'> " +
        "    <task name='step2Task'/> " +
        "    <transition name='' to='step3'/> " +
        "  </task-node>" +
        "  <task-node name='step3'> " +
        "    <task name='step3Task'/> " +
        "    <transition name='' to='end'/> " +
        "  </task-node> " +      
        "  <end-state name='end' />" +
        "</process-definition>"
      );
      
      JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
      try {
        jbpmContext.deployProcessDefinition(processDefinition);
      } finally {
        jbpmContext.close();
      }
    }

    public void startProcess() {

      JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
      try {

        GraphSession graphSession = jbpmContext.getGraphSession();
        
        ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition("deletetest");
        ProcessInstance processInstance = new ProcessInstance(processDefinition);
        processId = processInstance.getId();

        TaskInstance taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
        taskInstance.setVariableLocally("var1", "var1Value");
        taskInstance.end();
        Token token = taskInstance.getToken();
        currentTokenPath = token.getFullName();
        
        jbpmContext.save(processInstance);
      } finally {
        jbpmContext.close();
      }
    }

    public void step2TaskEnd() {

        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
        try {

          GraphSession graphSession = jbpmContext.getGraphSession();
          ProcessInstance processInstance = graphSession.loadProcessInstance(processId);
          Token token = processInstance.findToken(currentTokenPath);
          TaskMgmtSession taskSession = jbpmContext.getTaskMgmtSession();
          List tasks = taskSession.findTaskInstancesByToken(token.getId());
          TaskInstance taskInstance = (TaskInstance)tasks.get(0);

          //
          // comment out the following line and it works
          //
          taskInstance.setVariableLocally("var1", "var1TaskValue");

          taskInstance.setVariableLocally("var2", "var2UpdatedValue");
          taskInstance.end();
          token = taskInstance.getToken();
          currentTokenPath = token.getFullName();
          
          jbpmContext.save(processInstance);
        } finally {
          jbpmContext.close();
        }
      }

    
    public void deleteProcess()
    {
        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
        try {

          GraphSession graphSession = jbpmContext.getGraphSession();
          ProcessInstance processInstance = graphSession.loadProcessInstance(processId);
          graphSession.deleteProcessInstance(processInstance, true, true, true);
          //jbpmContext.save(processInstance);
        } finally {
          jbpmContext.close();
        }
    }
    
}

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the jboss-jira mailing list