Description of problem: Platform issue for JBPM-4030
Martin Weiler <mweiler> made a comment on jira JBPM-4030 Attaching a test process to reproduce the issue. Note that the end state is reached twice, and that inside the fork/join the parent/child token relationship is empty.
Martin Weiler <mweiler> made a comment on jira JBPM-4030 Proposal to fix this issue: {code} diff --git a/core/src/main/java/org/jbpm/graph/node/Join.java b/core/src/main/java/org/jbpm/graph/node/Join.java index bcff33a..9260e89 100644 --- a/core/src/main/java/org/jbpm/graph/node/Join.java +++ b/core/src/main/java/org/jbpm/graph/node/Join.java @@ -129,6 +129,10 @@ public class Join extends Node { } Token parentToken = arrivingToken.getParent(); + // JBPM-4030 refresh parent token if necessary + if(parentToken.getChildren().size()==0) { + executionContext.getJbpmContext().getSession().refresh(parentToken); + } boolean reactivateParent; // if this is a discriminator if (isDiscriminator) { @@ -173,7 +177,10 @@ public class Join extends Node { childToken.setAbleToReactivateParent(false); } // unlock parent token - parentToken.unlock(parentToken.getNode().toString()); + // JBPM-4030 check if parentToken can be unlocked + if(parentToken.isLocked() && parentToken.getLockOwner().equals(parentToken.getNode().toString())) { + parentToken.unlock(parentToken.getNode().toString()); + } // leave the join node leave(new ExecutionContext(parentToken)); } {code}
Marco Rietveld <marco.rietveld> made a comment on jira JBPM-4030 Martin, this is fantastic work! Thanks very much.
Marco Rietveld <marco.rietveld> made a comment on jira JBPM-4030 This is a note to myself for future reference: One of the main causes of this problem is the following code in the Fork class: {code:java} // phase two: create child token for each selected transition Map childTokens = new HashMap(); for (Iterator iter = transitionNames.iterator(); iter.hasNext();) { String transitionName = (String) iter.next(); Token childToken = createForkedToken(token, transitionName); childTokens.put(transitionName, childToken); } {code} Specifically, the {code:java}Map childTokens = new HashMap();{code} line is a lot more dangerous than it looks. *Why?* Because jBPM 3 uses the Hibernate 3 2nd level cache, which means that many of the objects referred to in the code, are actually hibernate-proxies of the actual objects. You'll notice that the method {{createForkedToken()}} is called, and your suspicion that creates the parent-child token relationship will be correct -- but only partially. *Here's what happens:* {{createdForkedToken()}} eventually calls the {{Token(Token parent, String name)}} constructor. And that constructor contains the following code: {code:java} this.parent = parent; parent.addChild(this); {code} Great! *NO..* Why? Because the parent object referred to here is the _actual_ object, not the hibernate-proxied Token object. That means that when we return to the original {{execute(...)}} in the {{Fork}} class, the hibernate-proxied (parent) Token object will still have *no* children! Blech.. And we return to why {{Map childTokens = new HashMap();}} is so dangerous. It should simply be this: {code:java}Map childTokens = token.getChildren();{code}. That way, we add the children to the hibernate-proxied Token object map. If you've been paying attention, you'll notice that we're now adding this (parent-child) relationship twice: once in the {{Fork.execute(...)}} method (with the above line), and once in the {{createForkedToken(...)}} method. This is okay for 2 reasons: # We're adding the same relationship: in both cases, the key is the transition name, and the value is the (same) child token reference. # Technically, we're adding this relationship to 2 different maps: the first map is from the hibernate-proxied parent Token, and the second map is from the (real) parent Token object.
Marco Rietveld <marco.rietveld> made a comment on jira JBPM-4030 Wow, there's an even simpler solution: simply initalize the {{Token.children}} (Map) field with a {{new HashMap()}} value so that the hibernate-proxied object also contains that field. LOL.
Marco Rietveld <marco.rietveld> updated the status of jira JBPM-4030 to Resolved