[JBoss jBPM] - org.hibernate.StaleObjectStateException: Row was updated or
by denica.gencheva
I have a "decision" node directly connected to a "join" node:
<decision name="HasSomeProperty">
| <transition to="join1" name="Yes"></transition>
| </decision>
| <join name="join1">
| </join>
I get the following exception during the execution of the process:
ERROR [STDERR] org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#2280181]
| at org.hibernate.persister.entity.AbstractEntityPersister.forceVersionIncrement(AbstractEntityPersister.java:1235)
| at org.hibernate.event.def.AbstractLockUpgradeEventListener.upgradeLock(AbstractLockUpgradeEventListener.java:82)
| at org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:64)
| at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:584)
| at org.hibernate.impl.SessionImpl.lock(SessionImpl.java:576)
| at org.jbpm.graph.node.Join.execute(Join.java:116)
| at org.jbpm.graph.def.Node.enter(Node.java:319)
| 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:585)
| at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
| at org.jbpm.graph.def.Node_$$_javassist_196.enter(Node_$$_javassist_196.java)
| at org.jbpm.graph.def.Transition.take(Transition.java:151)
| at org.jbpm.graph.def.Node.leave(Node.java:394)
| at org.jbpm.graph.exe.ExecutionContext.leaveNode(ExecutionContext.java:136)
| at org.jbpm.graph.node.Decision.execute(Decision.java:152)
| at org.jbpm.graph.def.Node.enter(Node.java:319)
| 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:585)
| at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
| at org.jbpm.graph.def.Node_$$_javassist_196.enter(Node_$$_javassist_196.java)
| at org.jbpm.graph.def.Transition.take(Transition.java:151)
| at org.jbpm.graph.def.Node.leave(Node.java:394)
| at org.jbpm.graph.def.Node.leave(Node.java:369)
| at org.jbpm.graph.node.Fork.execute(Fork.java:140)
| at org.jbpm.graph.def.Node.enter(Node.java:319)
| 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:585)
| at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
| at org.jbpm.graph.def.Node_$$_javassist_196.enter(Node_$$_javassist_196.java)
| at org.jbpm.graph.def.Transition.take(Transition.java:151)
| at org.jbpm.graph.def.Node.leave(Node.java:394)
| at org.jbpm.graph.node.StartState.leave(StartState.java:70)
| 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:585)
| at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
| at org.jbpm.graph.def.Node_$$_javassist_196.leave(Node_$$_javassist_196.java)
| at org.jbpm.graph.exe.Token.signal(Token.java:195)
| at org.jbpm.graph.exe.Token.signal(Token.java:140)
| at org.jbpm.graph.exe.ProcessInstance.signal(ProcessInstance.java:271)
| ...
The process is started from an EJB instance in JBoss AS 4.2.2. I'm using jBPM 3.2.2 and have its sources. I've found the exception is caused by the session.lock(parentToken, lockMode) statement at org.jbpm.graph.node.Join.execute(Join.java:116) because the Oracle DB (which I'm using) does not support LockMode.FORCE. During debugging, if I manually change the lockMode to UPGRADE it appears to work.
Further looking at the Join.execute() source:
if (session!=null) {
| LockMode lockMode = LockMode.FORCE;
| if (parentLockMode!=null) {
| lockMode = LockMode.parse(parentLockMode);
| }
| log.debug("forcing version increment on parent token "+parentToken);
| session.lock(parentToken, lockMode);
| }
I've seen the only way to change the lockMode run-time is to set the parentLockMode member field, which I've found could be done by setting a lock="pessimistic" attribute on the "join" element (org.jbpm.graph.node.Join class):
public void read(Element element, JpdlXmlReader jpdlReader) {
| String lock = element.attributeValue("lock");
| if ( (lock!=null)
| && (lock.equalsIgnoreCase("pessimistic"))
| ) {
| parentLockMode = LockMode.UPGRADE.toString();
| }
| }
so I've changed the "join" definition as:
<join name="join1" lock="pessimistic">
| </join>
So far so good, but while debugging I've found out the Join constructor is called 4 times and only two of the instances get the read method called therefore get lock mode set to UPGRADE. And then when I start the process, the instance of the Join which is used is one where parentLockMode is null and the lock mode is FORCE so I get the same exception again.
Why do we need LockMode.FORCE? Is it possible to change the LockMode to UPGRADE without changing jBPM source?
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4242235#4242235
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4242235
16 years, 9 months
[JBoss jBPM] - Re: Saving long spanning process in jBPM 4.0
by nazarfm
Let's say this is the workflow:
[img]http://img198.imageshack.us/img198/9325/screenshotukr.png[/img]
<process name="phoneCheckProcess" key="PCP" xmlns="http://jbpm.org/4.0/jpdl">
| <start g="72,187,48,48" name="start">
| <transition to="phoneCheck"/>
| </start>
|
| <state continue="async" g="211,178,92,52" name="phoneCheck">
| <on event="start">
| <event-listener class="eventListener.MyEventListener"/>
| </on>
| <transition to="proceed"/>
| </state>
| <state g="390,181,92,52" name="proceed">
| <transition to="end"/>
| </state>
| <end g="601,186,48,48" name="end" state="finished"/>
| </process>
When execution reaches MyEventListener, I call a web-service that is asynchronous (for testing purposes i use a mock). When that function completes, it calls a callbackHandler.
I have a class that keeps a static processEngine so that I can access it from my test case and callback handler.
In my test case;
ProcessInstance processInstance = MyController.getInstance().getExecutionService().startProcessInstanceByKey("PCP");
| Execution executionInQuery = processInstance.findActiveExecutionIn("phoneCheck");
| assertNotNull("Supposed to be <phoneCheck>", executionInQuery);
Here, things go like this. The web-service is called, and it calls the calbackHandler. The callback handler, accesses the static Process engine and does the following:
ProcessInstance instance = getInstance().getExecutionService().signalExecutionById(executionId);
where execution id is retrieved from the eventListener.
Now this gives me the exception that the executionId does not exist. I cannot figure this out. I have been trying various things here, but it still doesn't work. Any help or ideas would be greatly appreciated.
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4242178#4242178
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4242178
16 years, 9 months