Message Boards

Error when using workflow Fork with Condition that immediately was execute

thumbnail
Vahid Kh, modified 4 Years ago.

Error when using workflow Fork with Condition that immediately was execute

Junior Member Posts: 54 Join Date: 8/6/19 Recent Posts
Hello 
When I using Fork/Join with Condition that immediately was executed afterwards the below exception occured:

ERROR [liferay/kaleo_graph_walker-105][ParallelDestination:59] Unable to process message {destinationName=liferay/kaleo_graph_walker, response=null, responseDestinationName=null, responseId=null, payload=com.liferay.portal.workflow.kaleo.runtime.graph.PathElement@1172d069, values={defaultLocale=fa_IR, companyId=20101, groupId=0, principalName=20130, permissionChecker=com.liferay.portal.kernel.util.TransientValue@245cf11b, siteDefaultLocale=fa_IR, themeDisplayLocale=en_US}}
com.liferay.portal.kernel.messaging.MessageListenerException: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.liferay.portal.workflow.kaleo.model.impl.KaleoInstanceImpl#58884]
	at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:32)
	at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:74)
	at com.liferay.portal.messaging.internal.ParallelDestination$1.run(ParallelDestination.java:56)
	at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask._runTask(ThreadPoolExecutor.java:752)
	at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask.run(ThreadPoolExecutor.java:664)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.liferay.portal.workflow.kaleo.model.impl.KaleoInstanceImpl#58884]
	at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1950)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2595)
	at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2495)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2822)
	at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:113)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:185)
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
	at com.liferay.portal.dao.orm.hibernate.event.NestableFlushEventListener.onFlush(NestableFlushEventListener.java:61)
	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
	at com.liferay.portal.spring.hibernate.PortletTransactionManager$TransactionStatusWrapper.reset(PortletTransactionManager.java:260)
	at com.liferay.portal.spring.hibernate.PortletTransactionManager.commit(PortletTransactionManager.java:63)
	at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.commit(DefaultTransactionExecutor.java:41)
	at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:77)
	at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:57)
	at com.liferay.portal.service.ServiceContextAdvice.invoke(ServiceContextAdvice.java:60)
	at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:57)
	at com.liferay.portal.spring.aop.AopInvocationHandler.invoke(AopInvocationHandler.java:49)
	at com.sun.proxy.$Proxy698.updateKaleoInstance(Unknown Source)
	at com.liferay.portal.workflow.kaleo.runtime.internal.node.ConditionNodeExecutor.doExecute(ConditionNodeExecutor.java:68)
	at com.liferay.portal.workflow.kaleo.runtime.node.BaseNodeExecutor.execute(BaseNodeExecutor.java:83)
	at com.liferay.portal.workflow.kaleo.runtime.internal.graph.DefaultGraphWalker.follow(DefaultGraphWalker.java:74)
	at sun.reflect.GeneratedMethodAccessor544.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:50)
	at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:69)
	at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:57)
	at com.liferay.portal.spring.aop.AopInvocationHandler.invoke(AopInvocationHandler.java:49)
	at com.sun.proxy.$Proxy702.follow(Unknown Source)
	at com.liferay.portal.workflow.kaleo.runtime.internal.graph.messaging.PathElementMessageListener.doReceive(PathElementMessageListener.java:47)
	at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:26)
	... 5 more


the conditions script written in the simplest way for transparency
What is the problem??
thumbnail
David H Nebinger, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
So most of the time this message indicates that two pieces of code have retrieved the same entity, one made a change and persisted it, the second one made its own change and is trying to store it; basically it is holding a stale object that was modified by something else.

The solution is typically a fetch-then-update so you can eliminate the possibility of a stale object.

In your particular case, I think you're just suffering from the lack of any real logic built into your flow. There's nothing stopping or pausing as an entity goes through the workflow. And since everything is happening at once, you're seeing these kinds of simultaneous updates stepping on each other.
thumbnail
ali yeganeh, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Regular Member Posts: 148 Join Date: 5/1/19 Recent Posts
David H Nebinger:

So most of the time this message indicates that two pieces of code have retrieved the same entity, one made a change and persisted it, the second one made its own change and is trying to store it; basically it is holding a stale object that was modified by something else.

The solution is typically a fetch-then-update so you can eliminate the possibility of a stale object.

In your particular case, I think you're just suffering from the lack of any real logic built into your flow. There's nothing stopping or pausing as an entity goes through the workflow. And since everything is happening at once, you're seeing these kinds of simultaneous updates stepping on each other.

Hi David
I have this problem too.
According to your description , this is a problem that occurs in a multi-thread environment (  Race condition ) which is solved by synchronized keyword .
What is the solution when I need multiple tasks running concurrently, according to the that I do not know how the shared object is updated ?
According to the attachment file ,  I created 2 conditions and in the script wrote
         
returnValue = "MyTransition"  ;

This script is the cause of the exception.
thumbnail
David H Nebinger, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
ali yeganeh:

According to your description , this is a problem that occurs in a multi-thread environment (  Race condition ) which is solved by synchronized keyword .


What? I didn't say anything about threads or race conditions and synchronized keywords; synchronized wouldn't fix anything with the error the OP is reporting.
thumbnail
Vahid Kh, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Junior Member Posts: 54 Join Date: 8/6/19 Recent Posts
In my scenario, some of Reviews must be ignored so Conditions must go through join immediately. And because sometimes multiple conditions execute in one time it make error.How can I manage conditions that will run respectively?
thumbnail
ali yeganeh, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Regular Member Posts: 148 Join Date: 5/1/19 Recent Posts
David H Nebinger:

So most of the time this message indicates that two pieces of code have retrieved the same entity, one made a change and persisted it, the second one made its own change and is trying to store it; basically it is holding a stale object that was modified by something else.

The solution is typically a fetch-then-update so you can eliminate the possibility of a stale object.

In your particular case, I think you're just suffering from the lack of any real logic built into your flow. There's nothing stopping or pausing as an entity goes through the workflow. And since everything is happening at once, you're seeing these kinds of simultaneous updates stepping on each other.
Hi
This exception occurs when I add returnvalue  script to the condition, according to attache file.
Is it possible in fork or condition nodes to holding a stale object that was modified by something else?
thumbnail
David H Nebinger, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
I feel it is because of the speed at which both get evaluated. Since there is no code in the condition path, those two actions are happening simultaneously and they end up stepping on each other as a result.

I think if you added a Thread.sleep() call before the return, wait for like 250ms or something (simulating the condition checking something before returning a result), your issue would likely resolve itself since the simultaneous update on two paths would fall away.

While it looks like a race condition, it certainly is not solvable using a synchronized keyword because there are no methods being declared or invoked here.
thumbnail
ali yeganeh, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Regular Member Posts: 148 Join Date: 5/1/19 Recent Posts
Using Thread.sleep() is a safe code?
Is it possible to run two threads simultaneously.
I think fork and condition should manage this, for example, giving priority to threads.
Is there a solution to this problem?
thumbnail
David H Nebinger, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Liferay Legend Posts: 14916 Join Date: 9/2/06 Recent Posts
Get rid of the stubs and build out your whole workflow.

If it still fails with real code, then come back and share. This stub that you're using is not realistic enough.
thumbnail
ali yeganeh, modified 4 Years ago.

RE: Error when using workflow Fork with Condition that immediately was exe

Regular Member Posts: 148 Join Date: 5/1/19 Recent Posts
Hi David H Nebinger
I tried the workflow xml file in liferay 6.2 and 7.3 which worked correctly (attached file)
I think this problem was a bug in liferay 7.2 and fixed in 7.3.