Persist data in subprocess in call activity from multi instance

cancel
Showing results for 
Search instead for 
Did you mean: 
wkoonings
Member II

Persist data in subprocess in call activity from multi instance

I have a process where I call another subprocess in a loop. 

<code>

<callActivity id="callactivity_PickArticle" name="Pick article" calledElement="pickArticleSubProcess">
<extensionElements>
<activiti:in source="OrderLine" target="CurrentOrderLine"/>
</extensionElements>
<multiInstanceLoopCharacteristics isSequential="true" activiti:collection="${Order.orderLines}" activiti:elementVariable="OrderLine">

</multiInstanceLoopCharacteristics>
</callActivity>

<code>

This subprocess should update the passed element variable and in the end persist the changes to the database.

<code>

<process id="pickArticleSubProcess" name="Pick article process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask_ConfirmLocation" name="Go to location">
<extensionElements>
<activiti:formProperty id="locationCode" name="locationCode" required="true"></activiti:formProperty>
</extensionElements>
</userTask>
<userTask id="usertask_ConfirmQuantity" name="Confirm Quantity">
<extensionElements>
<activiti:formProperty id="quantity" name="quantity" required="true"></activiti:formProperty>
<activiti:formProperty id="reasonCode" name="reasonCode"></activiti:formProperty>
</extensionElements>
</userTask>
<sequenceFlow id="flow2" sourceRef="usertask_ConfirmLocation" targetRef="usertask_ConfirmQuantity"></sequenceFlow>
<serviceTask id="servicetask_BookArticle" name="Book article" activiti:delegateExpression="${BookArticleDelegate}"></serviceTask>
<sequenceFlow id="flow3" sourceRef="usertask_ConfirmQuantity" targetRef="servicetask_BookArticle"></sequenceFlow>
<sequenceFlow id="flow4" sourceRef="servicetask_BookArticle" targetRef="endevent1"></sequenceFlow>
<sequenceFlow id="flow5" sourceRef="startevent1" targetRef="usertask_ConfirmLocation"></sequenceFlow>
</process>

<code>

When I save the current orderline with: orderLineService.saveOrderLine(orderLine);, directly after the delegate the orderline is persisted. But when I complete the last orderline in the multi instance, all the orderlines, except the last one, are changed back to all the values null.

<code>

@Component("BookArticleDelegate")
public class BookArticleDelegate implements JavaDelegate {

@Autowired
private OrderLineService orderLineService;

@Override
public void execute(DelegateExecution de) {
OrderLine orderLine = (OrderLine) de.getVariable("CurrentOrderLine");

String sQuantity = (String) de.getVariable("quantity");
int quantity = Integer.parseInt(sQuantity);

String reason;

try {
reason = (String) de.getVariable("reasonCode");
orderLine.setReasonCode(reason);
} catch (Exception ex) {

}

orderLine.setPickedAmount(quantity);
orderLine.setHandled(true);

orderLineService.saveOrderLine(orderLine);
}
}

<code>

Something is going wrong, but I can't figure out what.

-- EDIT

I made the collection Order transient, because I believe it has something to do with managed entities that overwrite my own commits. Now after the first iteration through the multi instance call activity I get the following error:

<code>

Exception in thread "Thread-12" org.activiti.engine.ActivitiException: Could not execute inner activity behavior of multi instance behavior
at org.activiti.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior.leave(SequentialMultiInstanceBehavior.java:117)
at org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior.completed(MultiInstanceActivityBehavior.java:172)
at org.activiti.engine.impl.agenda.EndExecutionOperation.handleProcessInstanceExecution(EndExecutionOperation.java:98)
at org.activiti.engine.impl.agenda.EndExecutionOperation.handleRegularExecution(EndExecutionOperation.java:166)
at org.activiti.engine.impl.agenda.EndExecutionOperation.run(EndExecutionOperation.java:48)
at org.activiti.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:73)
at org.activiti.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:57)
at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:42)
at org.activiti.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:48)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:63)
at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:29)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:44)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:39)
at org.activiti.engine.impl.TaskServiceImpl.complete(TaskServiceImpl.java:186)
at com.mycompany.poc.inther.lc.workflow.workstation.engine.WorkflowEngineCore.completeTask(WorkflowEngineCore.java:102)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy83.completeTask(Unknown Source)
at com.mycompany.poc.inther.lc.workflow.workstation.WorkstationCore.handleTerminalTaskResponse(WorkstationCore.java:133)
at com.mycompany.poc.inther.lc.workflow.workstation.WorkstationCore$1.run(WorkstationCore.java:74)
Caused by: java.lang.NullPointerException
at org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior.executeOriginalBehavior(MultiInstanceActivityBehavior.java:199)
at org.activiti.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior.leave(SequentialMultiInstanceBehavior.java:109)
... 32 more

</code>

I found a JIRA issue which I believe covers the same problem, but I can't find the solution.

Activiti: Multi Instance Collapsed Sub Process - NullPointerException

3 Replies
afaust
Master

Re: Persist data in subprocess in call activity from multi instance

wkoonings
Member II

Re: Persist data in subprocess in call activity from multi instance

you're right, i'm sorry, i'm new to this forum, i removed the other post

cjose
Senior Member II

Re: Persist data in subprocess in call activity from multi instance

Strange issue.

Can you try adding the attribute activiti:async="true" to your call activity element and check if you see the same behaviour?

In the second part you mentioned that "I made the collection Order transient". Does it mean you tried the Transient Variable? If Transient Variable, I don't think it will work with your subprocess because you have a User Task in your subprocess and at that stage there is a wait state involved. Transient Variables do not survive beyond a wait state.