cancel
Showing results for 
Search instead for 
Did you mean: 

Versioning of Process Definitions

mauwarrior
Champ in-the-making
Champ in-the-making
FACT: The id property is set to {processDefinitionKey}:{processDefinitionVersion}:{generated-id},
*where generated-id is a unique number added to guarantee uniqueness of the process id for the process definition caches in a clustered environment.

Supposed I have a .bpmn file with the same processDefinitionKey(e.g. MyWorkflow) but the contents of the workflows are different. I deployed both of my .bpmn file pragmatically and both of them were successfully deployed. Deploying the first .bpmn file, I get these in my act_re_deployment table: MyWorkflow:1:3011. That is the id property set on my first deployment. Deploying the second .bpmn file, I get MyWorkflow:2:602804…Well, deployments were successful. But here's where the problem arises.

Since both deployments were successful, I tried to access it through my local server (PostgreSQL)…I login as admin account and both of my process workflow are present. But when I tried to click one of my process to start it..The following error occurred.

org.activiti.engine.ActivitiException:  Query return 2 results instead of max 1
   at org.activiti.engine.impl.AbstractQuery.executeSingleResult(AbstractQuery.java:162)
   at org.activiti.engine.impl.AbstractQuery.execute(AbstractQuery.java:141)
   at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:61)
   at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)
   at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:37)
   at org.activiti.engine.impl.AbstractQuery.singleResult(AbstractQuery.java:104)
   at ace.awsol.ssc.web.controller.core.ProcessController.startProcess(ProcessController.java:154)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
   at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
   at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
   at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
   at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
   at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
   at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
   at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
   at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
   at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
   at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
   at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
   at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
   at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
   at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
   at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
   at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
   at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
   at java.lang.Thread.run(Thread.java:662)

Therefore, I could not start any of the task from each of the workflow deployed.
Please how could I fix this. Thank you!
9 REPLIES 9

jbarrez
Star Contributor
Star Contributor
"org.activiti.engine.ActivitiException:  Query return 2 results instead of max 1"

Haven't I answered this before?

You need to use latestVersion() in the query in ace.awsol.ssc.web.controller.core.ProcessController.startProcess(ProcessController.java:154)

mauwarrior
Champ in-the-making
Champ in-the-making
Hi jbarrez,

The problem still persists even though I already added latestVersion on my ProcessController.startProcess.

@RequestMapping(value={"/{processKey}/start"}, method=RequestMethod.GET)
public String startProcess(@PathVariable("processKey") String processKey, ModelMap model) { 
   
  ProcessDefinition processDefinition = getActivitiService().getRepositoryService()
    .createProcessDefinitionQuery()
    .processDefinitionKey(processKey).latestVersion()
    .singleResult();

I tried running the codes again and return the same stack trace error as before. I suspect that since I deployed 2 .bpmn files with the same Id, there would be two instances of my process which returns an error on Abstract query? (I'm not sure about this). I wanted to attached a .jpeg file showing what happens after my first deployment and another deployment of the .bpmn but unfortunately I cannot do it here.

Additional info: I used the same bean for the two deployments.
Some fixes I had made:
* I tried to change the id of my second workflow and deployed it. Everything goes well.
* I deployed the new .bpmn file in a separate database. Everything goes well.

SImply saying:
I have two workflows with the same set of tasks.
First Workflow:      (Task 1, 2, 3, 6, 7,8)
Second Workflow:  (Task 1, 2, 3, 4, 5, 6, 7, 8)>>>Task 4 and Task 5 are the additional task, that is why I need to redeploy my Workflow but I am using the same (Controller, model, model config, validator, and java resources) for the two workflows since the second workflow is an upgraded version of the first workflow…If only I could bypass AbstractQuery not limiting the same instance of my deployment I could run both of my process even if they have the same processKey..

Everytime I deployed the same .bpmn file over and over again, a new instance of my processes is created and that is why I get the same error on abstract query. If I deployed it 5 times then the message error will say "Query results 5 instead of max 1"…

jbarrez
Star Contributor
Star Contributor
> "Everytime I deployed the same .bpmn file over and over again, a new instance of my processes is created "

That is the logic as expected.

> .processDefinitionKey(processKey).latestVersion()

This really should not give you two results. Do you have a unit test that shows this, cause I can't see how that is even possible.

mauwarrior
Champ in-the-making
Champ in-the-making
public class ProcessTestRequestToPurchasePH {

private String filename = "C:\\eclipse-workspace-activiti_v5\\Activiti_Test\\src\\main\\resources\\diagrams\\RequestToPurchasePH.bpmn";

@Rule
public ActivitiRule activitiRule = new ActivitiRule();

@Test
public void startProcess() throws Exception {
 
  //Codes for BPMN Deployment…
  RepositoryService repositoryService = activitiRule.getRepositoryService();
  repositoryService.createDeployment().addInputStream("RequestToPurchasePH.bpmn20.xml",
    new FileInputStream(filename)).deploy();
 
  RuntimeService runtimeService = activitiRule.getRuntimeService(); 
  Map<String, Object> variableMap = new HashMap<String, Object>();
  variableMap.put("applicant", null);
 
  ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("RequestToPurchasePH", variableMap);
  assertNotNull(processInstance.getId());
  System.out.println("id " + processInstance.getId() + " "
    + processInstance.getProcessDefinitionId());

Above is my junit test. I used the same unit test for my two deployments. I deployed first my first .bpmn file using the junit test above. Then, I need to modified my previous .bpmn file so I need to redeploy it using the same junit test.

jbarrez
Star Contributor
Star Contributor
Yes … so where's the part where the unit test is failing / not doing what you expect? Hard to say with only this bit of info.

mauwarrior
Champ in-the-making
Champ in-the-making


Follow-up please…

faizal-manan
Champ in-the-making
Champ in-the-making
it doesn't trigger any error on my side

<code>
@Test
    @Rollback(true)
    public void testProcess() {

        logger.debug("");
        repositoryService.createDeployment().addClasspathResource(RESOURCE_PATH).name(PROCESS_NAME).deploy();
        repositoryService.createDeployment().addClasspathResource(RESOURCE_PATH).name(PROCESS_NAME).deploy();

        Map<String, Object> variables = new HashMap<>();

        List<Deployment> deployments = processEngine.getRepositoryService().createDeploymentQuery().list();
        logger.debug("Deployment list {}",deployments.size());
        for (Deployment deployment : deployments) {
            logger.debug("DeploymentId {}, DeploymentName {}",deployment.getId(),deployment.getName());
        }

        variables.put("user", "zhangsan");
        ProcessInstance pi = runtimeService.startProcessInstanceByKey(PROCESS_NAME, variables);
        logger.debug("ProcessDefinitionId {}",pi.getProcessDefinitionId());
        logger.debug("DeploymentId {}",((ExecutionEntity) pi).getProcessDefinition().getDeploymentId());

    }
</code>

<code>
2016-05-19 01:17:14,168 DEBUG [main] (TwoDeploymentTest.java:58) - Deployment list 2
2016-05-19 01:17:14,169 DEBUG [main] (TwoDeploymentTest.java:60) - DeploymentId 1, DeploymentName jumpTask
2016-05-19 01:17:14,170 DEBUG [main] (TwoDeploymentTest.java:60) - DeploymentId 5, DeploymentName jumpTask
2016-05-19 01:17:14,238 DEBUG [main] (StartProcessListener.java:20) - [jumpTask:2:8-9] Process start jumpTask:2:8
2016-05-19 01:17:14,313 DEBUG [main] (TwoDeploymentTest.java:65) - ProcessDefinitionId jumpTask:2:8
2016-05-19 01:17:14,314 DEBUG [main] (TwoDeploymentTest.java:66) - DeploymentId 5
</code>

…I was not saying that the unit test failed or not doing what I expected. I am just stuck on the part where the two workflows were already deployed. I can now see in my "Processlist" two of my identical deployments but when I tried to start any of my process, I cannot continue since the error on AbstractQuery triggers the exception even if I followed your suggestions to put .latestVersion() on my ProcessController(). When tried adding .latestVersion() on my codes, my "Processlist" only shows one process and I was happy at first expecting that it resolved the issue. But when I tried to start the process, it still cannot continue since AbstractQuery throws the same exception, "Query results 2 instead of max 1".. Is this a bug?? If every deployments is given a unique instance id, then why it throws exception on query? Is it because I used the same deployment IDs for my two deployments?…I hope this info would be more enough to get the whole picture of the scenario.

Follow-up please…

jbarrez
Star Contributor
Star Contributor
> But when I tried to start the process, it still cannot continue since AbstractQuery throws the same exception, "Query results 2 instead of max 1".. Is this a bug??

That's where a unit test helps. You're saying in your list it's showing once … what list? Explorer? Your own UI?

How do you start your process? When you start by key, it will always use the latest.
We do need to know what code/environment/setup your running before we can answer better. We don't know the full context of at ace.awsol.ssc.web.controller.core.ProcessController.startProcess …