cancel
Showing results for 
Search instead for 
Did you mean: 

Delete Process Instance doesn't mark end of HistoricProcess instant and loses deleteReason

zoenzo
Champ in-the-making
Champ in-the-making
Hi,
I used RuntimeService.deleteProcessInstance to delete some old process instance by using the following code. The reason I add the processDefinition to the DeploymentCache is that they are some old definition and is not in the cache since the system has restarted many times.

if(pi.getEndTime()==null)
      {
         DeploymentCache dc =((ProcessEngineConfigurationImpl)processEngineConfiguration).getDeploymentManager().getProcessDefinitionCache();
         ProcessDefinitionEntity pd =(ProcessDefinitionEntity)dc.get(pi.getProcessDefinitionId());
         if(pd==null){
            pd = (ProcessDefinitionEntity)repositoryService.createProcessDefinitionQuery().processDefinitionId(pi.getProcessDefinitionId()).singleResult();
            dc.add(pi.getProcessDefinitionId(), pd);
            this.runtimeService.deleteProcessInstance(processId,"user delete");
            dc.remove(pi.getProcessDefinitionId());
         }
         else
            this.runtimeService.deleteProcessInstance(processId,"user delete");
      }
this.historyService.deleteHistoricProcessInstance(processId);

It throws a exception says that the process install is still running. After debugging, I found out that deleteProcessInstance method does not mark end of the historic process instance which means that the "endTime" field and "DELETE_REASON_" field in the database table "act_hi_procinst" is null after the method invoked.
Therefore, I search the forum and found out this issue is fixed in ACT-1098. But it still doesn't work in my project.
In my case, all the historic tasks are marked end with correct delete reason. But not the historic process instance.
Thus, I went to detail of the implementation code in ExecutionEntity.java.

public void deleteCascade(String deleteReason) {
    this.deleteReason = deleteReason;
    this.deleteRoot = true;
    performOperation(AtomicOperation.DELETE_CASCADE);
  }

After reading I haven't found any place in ExecutionEntity.java does the "mark end " work.
However, the HistoryManager.java, in the other hand, has the following code.

public void recordProcessInstanceEnd(String processInstanceId, String deleteReason, String activityId) {
   
    if(isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
      HistoricProcessInstanceEntity historicProcessInstance = getHistoricProcessInstanceManager()
              .findHistoricProcessInstance(processInstanceId);
     
      if (historicProcessInstance!=null) {
        historicProcessInstance.markEnded(deleteReason);
        historicProcessInstance.setEndActivityId(activityId);
      }
    }
  }

And the method is called from ExecutionImpl.

org.activiti.engine.impl.history.HistoryManager.recordProcessInstanceEnd(String, String, String)
      org.activiti.engine.impl.history.handler.ProcessInstanceEndHandler.notify(DelegateExecution)
             org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(InterpretableExecution)
                org.activiti.engine.impl.interceptor.CommandContext.performOperation(AtomicOperation, InterpretableExecution)
                      org.activiti.engine.impl.pvm.runtime.ExecutionImpl.performOperation(AtomicOperation)

So, what my code doesn't work. And I got confuse of ExecutionImpl with ExecutionEntity.
Or is there any other method to delete a process instance completely.
My version is from 5.8 at the begining and upgrade to 5.10 and to 5.12 now.
2 REPLIES 2

zoenzo
Champ in-the-making
Champ in-the-making
Currently, I use the following native sql to do the mark end. Is it Ok ? Can anyone help?
<java>
public void markProcessInstanceEnd(String processId)
{
  String sql="update act_hi_procinst set  END_TIME_=NOW(), DELETE_REASON_='Admin TEST' where ID_='"+processId+"'";
  SQLQuery query = this.getSession().
    createSQLQuery(sql);
  query.executeUpdate();
}
</java>

frederikherema1
Star Contributor
Star Contributor
I've added a test to master in github, asserting that the "deleteReason" is indeed set after deleting: https://github.com/Activiti/Activiti/commit/7b3575d50bbc1620f487ae0ce172edab25ceb9cb

Why not just query the actually non-historic Processinstances and delete them instead of using the Historic?