Author: alex.guizar(a)jboss.com
Date: 2009-02-11 21:19:59 -0500 (Wed, 11 Feb 2009)
New Revision: 3845
Modified:
jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/AbstractDbTestCase.java
jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/GraphSession.java
jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/JobSession.java
jbpm3/trunk/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java
jbpm3/trunk/modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
jbpm3/trunk/modules/core/src/test/java/org/jbpm/db/DeleteProcessInstanceDbTest.java
jbpm3/trunk/modules/core/src/test/java/org/jbpm/graph/exe/SubProcessCancellationTest.java
jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm2036/JBPM2036Test.java
Log:
JBPM-2036: prevent SOSE when repeating timer signals the token
supply missing findJobsWithOverdueLockTime query for LockMonitorThread
have deleteProcessInstance delete tasks as it is supposed to
Modified: jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/AbstractDbTestCase.java
===================================================================
--- jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/AbstractDbTestCase.java 2009-02-11
22:36:06 UTC (rev 3844)
+++ jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/AbstractDbTestCase.java 2009-02-12
02:19:59 UTC (rev 3845)
@@ -24,8 +24,6 @@
// $Id$
import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -45,7 +43,6 @@
import org.jbpm.taskmgmt.exe.TaskInstance;
public abstract class AbstractDbTestCase extends AbstractJbpmTestCase {
- private static final Log log = LogFactory.getLog(AbstractDbTestCase.class);
protected JbpmConfiguration jbpmConfiguration;
@@ -61,6 +58,8 @@
protected JobExecutor jobExecutor;
+ private static final Log log = LogFactory.getLog(AbstractDbTestCase.class);
+
protected void setUp() throws Exception {
super.setUp();
beginSessionTransaction();
@@ -185,31 +184,19 @@
}
protected void waitForJobs(long timeout) {
- // install a timer that will interrupt if it takes too long
- // if that happens, it will lead to an interrupted exception and the test will fail
- TimerTask interruptTask = new TimerTask() {
- Thread testThread = Thread.currentThread();
-
- public void run() {
- log.debug("test " + getName() + " took too long. going to
interrupt...");
- testThread.interrupt();
+ long startTime = System.currentTimeMillis();
+ while (getNbrOfJobsAvailable() > 0) {
+ if (System.currentTimeMillis() - startTime > timeout) {
+ fail("test execution exceeded treshold of " + timeout + "
milliseconds");
}
- };
- Timer timer = new Timer();
- timer.schedule(interruptTask, timeout);
-
- try {
- while (getNbrOfJobsAvailable() > 0) {
- log.debug("going to sleep for 200 millis, waiting for the job executor to
process more jobs");
- Thread.sleep(200);
+ log.debug("waiting for the job executor to process more jobs");
+ try {
+ Thread.sleep(500);
}
+ catch (InterruptedException e) {
+ // keep going
+ }
}
- catch (InterruptedException e) {
- fail("test execution exceeded treshold of " + timeout + "
milliseconds");
- }
- finally {
- timer.cancel();
- }
}
protected int getNbrOfJobsAvailable() {
Modified: jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/GraphSession.java
===================================================================
--- jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/GraphSession.java 2009-02-11
22:36:06 UTC (rev 3844)
+++ jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/GraphSession.java 2009-02-12
02:19:59 UTC (rev 3845)
@@ -28,10 +28,8 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
-import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.jbpm.JbpmException;
@@ -96,7 +94,7 @@
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't save process definition '" +
processDefinition + "'", e);
+ throw new JbpmException("could not save " + processDefinition, e);
}
}
@@ -107,11 +105,12 @@
*/
public ProcessDefinition loadProcessDefinition(long processDefinitionId) {
try {
- return (ProcessDefinition) session.load(ProcessDefinition.class, new
Long(processDefinitionId));
+ return (ProcessDefinition) session.load(ProcessDefinition.class,
+ new Long(processDefinitionId));
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't load process definition '" +
processDefinitionId + "'", e);
+ throw new JbpmException("could not load process definition " +
processDefinitionId, e);
}
}
@@ -126,7 +125,7 @@
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't get process definition '" +
processDefinitionId + "'", e);
+ throw new JbpmException("could not get process definition " +
processDefinitionId, e);
}
}
@@ -134,40 +133,35 @@
* queries the database for a process definition with the given name and version.
*/
public ProcessDefinition findProcessDefinition(String name, int version) {
- ProcessDefinition processDefinition = null;
try {
- Query query =
session.getNamedQuery("GraphSession.findProcessDefinitionByNameAndVersion");
- query.setString("name", name);
- query.setInteger("version", version);
- processDefinition = (ProcessDefinition) query.uniqueResult();
+ return (ProcessDefinition)
session.getNamedQuery("GraphSession.findProcessDefinitionByNameAndVersion")
+ .setString("name", name)
+ .setInteger("version", version)
+ .uniqueResult();
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't get process definition with name
'"
+ throw new JbpmException("could not find process definition '"
+ name
- + "' and version '"
- + version
- + "'", e);
+ + "' at version "
+ + version, e);
}
- return processDefinition;
}
/**
* queries the database for the latest version of a process definition with the given
name.
*/
public ProcessDefinition findLatestProcessDefinition(String name) {
- ProcessDefinition processDefinition = null;
try {
- Query query =
session.getNamedQuery("GraphSession.findLatestProcessDefinitionQuery");
- query.setString("name", name);
- query.setMaxResults(1);
- processDefinition = (ProcessDefinition) query.uniqueResult();
+ return (ProcessDefinition)
session.getNamedQuery("GraphSession.findLatestProcessDefinitionQuery")
+ .setString("name", name)
+ .setMaxResults(1)
+ .uniqueResult();
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't find process definition '" +
name + "'", e);
+ throw new JbpmException("could not find process definition '" + name
+ "'", e);
}
- return processDefinition;
}
/**
@@ -176,11 +170,10 @@
*/
public List<ProcessDefinition> findLatestProcessDefinitions() {
try {
- Query query =
session.getNamedQuery("GraphSession.findLatestProcessDefinitions");
- List<Object[]> tuples = CollectionUtil.checkList(query.list(),
Object[].class);
-
+ List<?> tuples =
session.getNamedQuery("GraphSession.findLatestProcessDefinitions")
+ .list();
List<ProcessDefinition> result = new ArrayList<ProcessDefinition>();
- for (Object[] tuple : tuples) {
+ for (Object[] tuple : CollectionUtil.checkList(tuples, Object[].class)) {
String name = (String) tuple[0];
Integer version = (Integer) tuple[1];
result.add(findProcessDefinition(name, version));
@@ -189,14 +182,15 @@
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't find latest versions of process
definitions", e);
+ throw new JbpmException("could not find latest versions of process
definitions", e);
}
}
public List<ProcessDefinition> findProcessDefinitions(Collection<Long>
processDefinitionIds) {
- Criteria criteria = session.createCriteria(ProcessDefinition.class)
- .add(Restrictions.in("id", processDefinitionIds));
- return CollectionUtil.checkList(criteria.list(), ProcessDefinition.class);
+ List<?> processDefinitions = session.createCriteria(ProcessDefinition.class)
+ .add(Restrictions.in("id", processDefinitionIds))
+ .list();
+ return CollectionUtil.checkList(processDefinitions, ProcessDefinition.class);
}
/**
@@ -205,12 +199,13 @@
*/
public List<ProcessDefinition> findAllProcessDefinitions() {
try {
- Query query =
session.getNamedQuery("GraphSession.findAllProcessDefinitions");
- return CollectionUtil.checkList(query.list(), ProcessDefinition.class);
+ List<?> processDefinitions =
session.getNamedQuery("GraphSession.findAllProcessDefinitions")
+ .list();
+ return CollectionUtil.checkList(processDefinitions, ProcessDefinition.class);
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't find all process definitions", e);
+ throw new JbpmException("could not find all process definitions", e);
}
}
@@ -220,13 +215,14 @@
*/
public List<ProcessDefinition> findAllProcessDefinitionVersions(String name) {
try {
- Query query =
session.getNamedQuery("GraphSession.findAllProcessDefinitionVersions");
- query.setString("name", name);
- return CollectionUtil.checkList(query.list(), ProcessDefinition.class);
+ List<?> processDefinitions =
session.getNamedQuery("GraphSession.findAllProcessDefinitionVersions")
+ .setString("name", name)
+ .list();
+ return CollectionUtil.checkList(processDefinitions, ProcessDefinition.class);
}
catch (HibernateException e) {
log.error(e);
- throw new JbpmException("couldn't find all versions of process definition
'" + name + "'", e);
+ throw new JbpmException("could not find all versions of process definition
'" + name + "'", e);
}
}
@@ -236,12 +232,22 @@
public void deleteProcessDefinition(ProcessDefinition processDefinition) {
if (processDefinition == null) {
- throw new JbpmException("processDefinition is null");
+ throw new IllegalArgumentException("processDefinition cannot be null");
}
+
try {
// delete all the process instances of this definition
- for (ProcessInstance processInstance; ((processInstance =
findNextProcessInstance(processDefinition)) != null);) {
- deleteProcessInstance(processInstance);
+ List<?> processInstanceIds =
session.getNamedQuery("GraphSession.findAllProcessInstanceIdsForDefinition")
+ .setLong("processDefinitionId", processDefinition.getId())
+ .list();
+ for (Long processInstanceId : CollectionUtil.checkList(processInstanceIds,
Long.class)) {
+ ProcessInstance processInstance = getProcessInstance(processInstanceId);
+ if (processInstance != null) {
+ deleteProcessInstance(processInstance);
+ }
+ else {
+ log.debug("process instance " + processInstanceId + " has been
deleted already");
+ }
}
List<ProcessState> referencingProcessStates =
findReferencingProcessStates(processDefinition);
@@ -254,25 +260,17 @@
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't delete process definition '"
- + processDefinition.getId()
- + "'", e);
+ throw new JbpmException("could not delete " + processDefinition, e);
}
}
- protected ProcessInstance findNextProcessInstance(ProcessDefinition processDefinition)
{
- return (ProcessInstance) session.createCriteria(ProcessInstance.class)
- .add(Restrictions.eq("processDefinition", processDefinition))
- .setMaxResults(1)
- .uniqueResult();
+ List<ProcessState> findReferencingProcessStates(ProcessDefinition
subProcessDefinition) {
+ List<?> processStates =
session.getNamedQuery("GraphSession.findReferencingProcessStates")
+ .setEntity("subProcessDefinition", subProcessDefinition)
+ .list();
+ return CollectionUtil.checkList(processStates, ProcessState.class);
}
- protected List<ProcessState> findReferencingProcessStates(ProcessDefinition
subProcessDefinition) {
- Query query =
session.getNamedQuery("GraphSession.findReferencingProcessStates");
- query.setEntity("subProcessDefinition", subProcessDefinition);
- return CollectionUtil.checkList(query.list(), ProcessState.class);
- }
-
// process instances ////////////////////////////////////////////////////////
/**
@@ -292,13 +290,11 @@
*/
public ProcessInstance loadProcessInstance(long processInstanceId) {
try {
- ProcessInstance processInstance = (ProcessInstance)
session.load(ProcessInstance.class, new Long(
- processInstanceId));
- return processInstance;
+ return (ProcessInstance) session.load(ProcessInstance.class, new
Long(processInstanceId));
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't load process instance '" +
processInstanceId + "'", e);
+ throw new JbpmException("could not load process instance " +
processInstanceId, e);
}
}
@@ -308,13 +304,11 @@
*/
public ProcessInstance getProcessInstance(long processInstanceId) {
try {
- ProcessInstance processInstance = (ProcessInstance)
session.get(ProcessInstance.class, new Long(
- processInstanceId));
- return processInstance;
+ return (ProcessInstance) session.get(ProcessInstance.class, new
Long(processInstanceId));
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't get process instance '" +
processInstanceId + "'", e);
+ throw new JbpmException("could not get process instance " +
processInstanceId, e);
}
}
@@ -326,12 +320,11 @@
*/
public Token loadToken(long tokenId) {
try {
- Token token = (Token) session.load(Token.class, new Long(tokenId));
- return token;
+ return (Token) session.load(Token.class, new Long(tokenId));
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't load token '" + tokenId +
"'", e);
+ throw new JbpmException("could not load token " + tokenId, e);
}
}
@@ -342,12 +335,11 @@
*/
public Token getToken(long tokenId) {
try {
- Token token = (Token) session.get(Token.class, new Long(tokenId));
- return token;
+ return (Token) session.get(Token.class, new Long(tokenId));
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't get token '" + tokenId +
"'", e);
+ throw new JbpmException("could not get token " + tokenId, e);
}
}
@@ -355,7 +347,13 @@
* locks a process instance in the database.
*/
public void lockProcessInstance(long processInstanceId) {
- lockProcessInstance(loadProcessInstance(processInstanceId));
+ try {
+ session.load(ProcessInstance.class, processInstanceId, LockMode.UPGRADE);
+ }
+ catch (Exception e) {
+ handle(e);
+ throw new JbpmException("could not lock process instance " +
processInstanceId, e);
+ }
}
/**
@@ -367,7 +365,7 @@
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't lock process instance '" +
processInstance.getId() + "'", e);
+ throw new JbpmException("could not lock " + processInstance, e);
}
}
@@ -377,15 +375,15 @@
*/
public List<ProcessInstance> findProcessInstances(long processDefinitionId) {
try {
- Query query =
session.getNamedQuery("GraphSession.findAllProcessInstancesForADefinition");
- query.setLong("processDefinitionId", processDefinitionId);
- return CollectionUtil.checkList(query.list(), ProcessInstance.class);
+ List<?> processInstances =
session.getNamedQuery("GraphSession.findAllProcessInstancesForDefinition")
+ .setLong("processDefinitionId", processDefinitionId)
+ .list();
+ return CollectionUtil.checkList(processInstances, ProcessInstance.class);
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't load process instances for process
definition '"
- + processDefinitionId
- + "'", e);
+ throw new JbpmException("could not find process instances for process
definition "
+ + processDefinitionId, e);
}
}
@@ -399,89 +397,82 @@
public void deleteProcessInstance(ProcessInstance processInstance, boolean
includeTasks,
boolean includeJobs) {
- if (processInstance == null)
- throw new JbpmException("processInstance is null in
JbpmSession.deleteProcessInstance()");
- log.debug("deleting process instance " + processInstance.getId());
+ if (processInstance == null) {
+ throw new IllegalArgumentException("processInstance cannot be null");
+ }
try {
- // jobs
+ // delete outstanding jobs
if (includeJobs) {
- log.debug("deleting jobs for process instance " +
processInstance.getId());
- Query query =
session.getNamedQuery("GraphSession.deleteJobsForProcessInstance");
- query.setEntity("processInstance", processInstance);
- query.executeUpdate();
+ log.debug("deleting jobs for " + processInstance);
+ int entityCount =
session.getNamedQuery("GraphSession.deleteJobsForProcessInstance")
+ .setEntity("processInstance", processInstance)
+ .executeUpdate();
+ log.debug("deleted " + entityCount + " jobs for " +
processInstance);
}
- // tasks
- if (includeTasks) {
- Query query =
session.getNamedQuery("GraphSession.findTaskInstanceIdsForProcessInstance");
- query.setEntity("processInstance", processInstance);
- List<Long> taskInstanceIds = CollectionUtil.checkList(query.list(),
Long.class);
-
- if (!taskInstanceIds.isEmpty()) {
- log.debug("deleting tasks "
- + taskInstanceIds
- + " for process instance "
- + processInstance.getId());
- query =
session.getNamedQuery("GraphSession.deleteTaskInstancesById");
- query.setParameterList("taskInstanceIds", taskInstanceIds);
- }
- }
-
- // delete the logs
- log.debug("deleting logs for process instance " +
processInstance.getId());
+ // delete logs
+ log.debug("deleting logs for " + processInstance);
deleteLogs(processInstance);
- // delete the tokens and subprocess instances
- log.debug("deleting subprocesses for process instance " +
processInstance.getId());
- deleteSubProcesses(processInstance.getRootToken());
-
- // null out the parent process token
+ // detach from parent process token
Token superProcessToken = processInstance.getSuperProcessToken();
if (superProcessToken != null) {
- log.debug("nulling property subProcessInstance in superProcessToken "
- + superProcessToken.getId()
- + " which is referencing the process instance "
- + processInstance.getId()
- + " which is being deleted");
+ log.debug("detaching "
+ + processInstance
+ + " from super process token "
+ + superProcessToken.getId());
+ processInstance.setSuperProcessToken(null);
superProcessToken.setSubProcessInstance(null);
}
- // add the process instance
- log.debug("hibernate session delete for process instance " +
processInstance.getId());
+ // delete tokens and subprocess instances
+ log.debug("deleting subprocesses for " + processInstance);
+ deleteSubProcesses(processInstance);
+
+ // delete tasks (TaskLogs reference tasks, so tasks must be deleted after logs)
+ if (includeTasks) {
+ log.debug("deleting tasks for " + processInstance);
+ List<?> tasks =
session.getNamedQuery("GraphSession.findTaskInstancesForProcessInstance")
+ .setEntity("processInstance", processInstance)
+ .list();
+ for (Object task : tasks) {
+ session.delete(task);
+ }
+ }
+
+ // delete the process instance
+ log.debug("deleting " + processInstance);
session.delete(processInstance);
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't delete process instance '" +
processInstance.getId() + "'",
- e);
+ throw new JbpmException("could not delete " + processInstance, e);
}
}
void deleteLogs(ProcessInstance processInstance) {
- Query query =
session.getNamedQuery("GraphSession.findLogsForProcessInstance");
- query.setEntity("processInstance", processInstance);
- List<ProcessLog> logs = CollectionUtil.checkList(query.list(),
ProcessLog.class);
- for (ProcessLog processLog : logs) {
+ List<?> logs =
session.getNamedQuery("GraphSession.findLogsForProcessInstance")
+ .setEntity("processInstance", processInstance)
+ .list();
+ for (ProcessLog processLog : CollectionUtil.checkList(logs, ProcessLog.class)) {
session.delete(processLog);
}
}
- void deleteSubProcesses(Token token) {
- if (token != null) {
- Query query =
session.getNamedQuery("GraphSession.findSubProcessInstances");
- query.setEntity("processInstance", token.getProcessInstance());
- List<ProcessInstance> subProcessInstances =
CollectionUtil.checkList(query.list(), ProcessInstance.class);
+ void deleteSubProcesses(ProcessInstance processInstance) {
+ if (processInstance != null) {
+ List<?> subProcessInstances =
session.getNamedQuery("GraphSession.findSubProcessInstances")
+ .setEntity("processInstance", processInstance)
+ .list();
if (subProcessInstances.isEmpty()) {
- log.debug("no subprocesses to delete for token " + token.getId());
+ log.debug("no subprocesses to delete for " + processInstance);
return;
}
- for (ProcessInstance subProcessInstance : subProcessInstances) {
- log.debug("deleting sub process " + subProcessInstance.getId());
- subProcessInstance.setSuperProcessToken(null);
- token.setSubProcessInstance(null);
+ for (ProcessInstance subProcessInstance :
CollectionUtil.checkList(subProcessInstances, ProcessInstance.class)) {
+ log.debug("preparing to delete sub process instance " +
subProcessInstance.getId());
deleteProcessInstance(subProcessInstance);
}
}
@@ -545,19 +536,19 @@
}
}
- public List<AverageNodeTimeEntry> calculateAverageTimeByNode(final long
processDefinitionId,
- final long minumumDurationMillis) {
+ public List<AverageNodeTimeEntry> calculateAverageTimeByNode(long
processDefinitionId,
+ long minumumDurationMillis) {
try {
- Query query =
session.getNamedQuery("GraphSession.calculateAverageTimeByNode");
- query.setLong("processDefinitionId", processDefinitionId);
- query.setDouble("minimumDuration", minumumDurationMillis);
- List<Object[]> listResults = CollectionUtil.checkList(query.list(),
Object[].class);
+ List<?> tuples =
session.getNamedQuery("GraphSession.calculateAverageTimeByNode")
+ .setLong("processDefinitionId", processDefinitionId)
+ .setDouble("minimumDuration", minumumDurationMillis)
+ .list();
List<AverageNodeTimeEntry> results;
- if (!listResults.isEmpty()) {
+ if (!tuples.isEmpty()) {
results = new ArrayList<AverageNodeTimeEntry>();
- for (Object[] values : listResults) {
+ for (Object[] values : CollectionUtil.checkList(tuples, Object[].class)) {
AverageNodeTimeEntry averageNodeTimeEntry = new AverageNodeTimeEntry();
averageNodeTimeEntry.setNodeId(((Number) values[0]).longValue());
averageNodeTimeEntry.setNodeName((String) values[1]);
@@ -576,63 +567,48 @@
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't load process instances for process
definition '"
- + processDefinitionId
- + "'", e);
+ throw new JbpmException("could not calculate average time by node for process
definition "
+ + processDefinitionId, e);
}
}
public List<Node> findActiveNodesByProcessInstance(ProcessInstance
processInstance) {
try {
- Query query =
session.getNamedQuery("GraphSession.findActiveNodesByProcessInstance");
- query.setEntity("processInstance", processInstance);
- return CollectionUtil.checkList(query.list(), Node.class);
+ List<?> nodes =
session.getNamedQuery("GraphSession.findActiveNodesByProcessInstance")
+ .setEntity("processInstance", processInstance)
+ .list();
+ return CollectionUtil.checkList(nodes, Node.class);
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't active nodes for process instance
'"
- + processInstance
- + "'", e);
+ throw new JbpmException("could not find active nodes for " +
processInstance, e);
}
}
public ProcessInstance getProcessInstance(ProcessDefinition processDefinition, String
key) {
- ProcessInstance processInstance = null;
try {
- Query query =
session.getNamedQuery("GraphSession.findProcessInstanceByKey");
- query.setEntity("processDefinition", processDefinition);
- query.setString("key", key);
- processInstance = (ProcessInstance) query.uniqueResult();
+ return (ProcessInstance)
session.getNamedQuery("GraphSession.findProcessInstanceByKey")
+ .setEntity("processDefinition", processDefinition)
+ .setString("key", key)
+ .uniqueResult();
}
catch (Exception e) {
handle(e);
- throw new JbpmException("couldn't get process instance with key
'" + key + "'", e);
+ throw new JbpmException("could not get process instance with key '" +
key + "'", e);
}
- return processInstance;
}
public ProcessInstance loadProcessInstance(ProcessDefinition processDefinition, String
key) {
- ProcessInstance processInstance = null;
- try {
- Query query =
session.getNamedQuery("GraphSession.findProcessInstanceByKey");
- query.setEntity("processDefinition", processDefinition);
- query.setString("key", key);
- processInstance = (ProcessInstance) query.uniqueResult();
- if (processInstance == null) {
- throw new JbpmException("no process instance was found with key " +
key);
- }
+ ProcessInstance processInstance = getProcessInstance(processDefinition, key);
+ if (processInstance == null) {
+ throw new JbpmException("no process instance was found with key '" +
key + "'");
}
- catch (Exception e) {
- handle(e);
- throw new JbpmException("couldn't load process instance with key
'" + key + "'", e);
- }
return processInstance;
}
private void handle(Exception e) {
log.error(e);
- if (jbpmSession != null)
- jbpmSession.handleException();
+ if (jbpmSession != null) jbpmSession.handleException();
}
private static final Log log = LogFactory.getLog(GraphSession.class);
Modified: jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/JobSession.java
===================================================================
--- jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/JobSession.java 2009-02-11 22:36:06
UTC (rev 3844)
+++ jbpm3/trunk/modules/core/src/main/java/org/jbpm/db/JobSession.java 2009-02-12 02:19:59
UTC (rev 3845)
@@ -21,13 +21,14 @@
*/
package org.jbpm.db;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
@@ -48,187 +49,227 @@
}
public Job getFirstAcquirableJob(String lockOwner) {
- Job job = null;
try {
- Query query = session.getNamedQuery("JobSession.getFirstAcquirableJob");
- query.setString("lockOwner", lockOwner);
- query.setTimestamp("now", new Date());
- query.setMaxResults(1);
- job = (Job) query.uniqueResult();
-
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't get acquirable jobs", e);
+ return (Job) session.getNamedQuery("JobSession.getFirstAcquirableJob")
+ .setString("lockOwner", lockOwner)
+ .setTimestamp("now", new Date())
+ .setMaxResults(1)
+ .uniqueResult();
}
- return job;
+ catch (HibernateException e) {
+ throw new JbpmException("could not get first acquirable job", e);
+ }
}
public List<Job> findExclusiveJobs(String lockOwner, ProcessInstance
processInstance) {
try {
- Query query = session.getNamedQuery("JobSession.findExclusiveJobs");
- query.setString("lockOwner", lockOwner);
- query.setTimestamp("now", new Date());
- query.setParameter("processInstance", processInstance);
- return CollectionUtil.checkList(query.list(), Job.class);
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't find exclusive jobs for thread
'"+lockOwner+"' and process instance
'"+processInstance+"'", e);
+ List<?> jobs =
session.getNamedQuery("JobSession.findExclusiveJobs")
+ .setString("lockOwner", lockOwner)
+ .setTimestamp("now", new Date())
+ .setParameter("processInstance", processInstance)
+ .list();
+ return CollectionUtil.checkList(jobs, Job.class);
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not find exclusive jobs owned by '"
+ + lockOwner
+ + "' for "
+ + processInstance, e);
+ }
}
-
- /**
- * find all jobs
- */
+
public List<Job> findJobsByToken(Token token) {
try {
- Query query = session.getNamedQuery("JobSession.findJobsByToken");
- query.setParameter("token", token);
- return CollectionUtil.checkList(query.list(), Job.class);
- } catch (Exception e) {
- throw new JbpmException("couldn't find jobs for token
'"+token+"'", e);
+ List<?> jobs = session.getNamedQuery("JobSession.findJobsByToken")
+ .setParameter("token", token)
+ .list();
+ return CollectionUtil.checkList(jobs, Job.class);
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not find jobs for " + token, e);
+ }
}
- public Job getFirstDueJob(String lockOwner, Collection<Long> jobIdsToIgnore) {
- Job job = null;
+ public Job getFirstDueJob(String lockOwner, Collection<Long> monitoredJobs) {
try {
- Query query = null;
- if ( (jobIdsToIgnore==null)
- || (jobIdsToIgnore.isEmpty() )
- ) {
+ Query query;
+ if (monitoredJobs == null || monitoredJobs.isEmpty()) {
query = session.getNamedQuery("JobSession.getFirstDueJob");
- query.setString("lockOwner", lockOwner);
-
- } else {
- query =
session.getNamedQuery("JobSession.getFirstDueJobExlcMonitoredJobs");
- query.setString("lockOwner", lockOwner);
- query.setParameterList("jobIdsToIgnore", jobIdsToIgnore);
-
}
- query.setMaxResults(1);
- job = (Job) query.uniqueResult();
-
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't get acquirable jobs", e);
+ else {
+ query =
session.getNamedQuery("JobSession.getFirstDueJobExcludingMonitoredJobs");
+ query.setParameterList("monitoredJobIds", monitoredJobs);
+ }
+ return (Job) query.setString("lockOwner", lockOwner)
+ .setMaxResults(1)
+ .uniqueResult();
}
- return job;
+ catch (HibernateException e) {
+ throw new JbpmException("could not get first due job owned by '"
+ + lockOwner
+ + "' ignoring jobs "
+ + monitoredJobs, e);
+ }
}
public void saveJob(Job job) {
- session.saveOrUpdate(job);
- if (job instanceof Timer) {
- Timer timer = (Timer) job;
- Action action = timer.getAction();
- if (action != null && !session.contains(action)) {
- log.debug("cascading timer save to action");
- session.save(action);
+ try {
+ session.saveOrUpdate(job);
+ if (job instanceof Timer) {
+ Timer timer = (Timer) job;
+ Action action = timer.getAction();
+ if (action != null && !session.contains(action)) {
+ log.debug("cascading save from " + job + " to " + action);
+ session.save(action);
+ }
}
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not save " + job, e);
+ }
}
public void deleteJob(Job job) {
- session.delete(job);
+ try {
+ session.delete(job);
+ log.debug("deleted " + job);
+ }
+ catch (HibernateException e) {
+ throw new JbpmException("could not delete " + job, e);
+ }
}
public Job loadJob(long jobId) {
try {
return (Job) session.load(Job.class, new Long(jobId));
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't load job
'"+jobId+"'", e);
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not load job " + jobId, e);
+ }
}
public Timer loadTimer(long timerId) {
try {
return (Timer) session.load(Timer.class, new Long(timerId));
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't load timer " + timerId, e);
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not load timer " + timerId, e);
+ }
}
public List<Job> loadJobs(long... jobIds) {
- Criteria criteria = session.createCriteria(Job.class)
- .add(Restrictions.in("id", toObjectArray(jobIds)));
- return CollectionUtil.checkList(criteria.list(), Job.class);
+ try {
+ List<?> jobs = session.createCriteria(Job.class)
+ .add(Restrictions.in("id", toObjectArray(jobIds)))
+ .list();
+ return CollectionUtil.checkList(jobs, Job.class);
+ }
+ catch (HibernateException e) {
+ throw new JbpmException("could not load jobs " + Arrays.toString(jobIds),
e);
+ }
}
+ private static Long[] toObjectArray(long[] primitives) {
+ final int length = primitives.length;
+ Long[] objects = new Long[length];
+ for (int i = 0; i < length; i++) {
+ objects[i] = primitives[i];
+ }
+ return objects;
+ }
+
public Job getJob(long jobId) {
try {
return (Job) session.get(Job.class, new Long(jobId));
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't get job
'"+jobId+"'", e);
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not get job " + jobId, e);
+ }
}
public void suspendJobs(Token token) {
try {
- Query query = session.getNamedQuery("JobSession.suspendJobs");
- query.setParameter("token", token);
- query.executeUpdate();
-
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't suspend jobs for "+token, e);
+
session.getNamedQuery("JobSession.suspendJobs").setParameter("token",
token).executeUpdate();
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not suspend jobs for " + token, e);
+ }
}
public void resumeJobs(Token token) {
try {
- Query query = session.getNamedQuery("JobSession.resumeJobs");
- query.setParameter("token", token);
- query.executeUpdate();
-
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't resume jobs for "+token, e);
+
session.getNamedQuery("JobSession.resumeJobs").setParameter("token",
token).executeUpdate();
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not resume jobs for " + token, e);
+ }
}
public void deleteTimersByName(String name, Token token) {
try {
- log.debug("deleting timers by name '" + name + "' for "
+ token);
- Query query = session.getNamedQuery("JobSession.deleteTimersByName");
- query.setString("name", name);
- query.setParameter("token", token);
- int entityCount = query.executeUpdate();
- log.debug(entityCount + " timers by name '" + name + "' for
" + token + " were deleted");
- } catch (Exception e) {
- log.error(e);
- throw new JbpmException("couldn't delete timers by name '" + name
+ "' for " + token, e);
+ // delete unowned timers
+ int entityCount = session.getNamedQuery("JobSession.deleteTimersByName")
+ .setString("name", name)
+ .setParameter("token", token)
+ .executeUpdate();
+ log.debug("deleted " + entityCount + " timers by name '" +
name + "' for " + token);
+
+ // prevent further repetitions
+ List<?> timers =
session.getNamedQuery("JobSession.findRepeatingTimersByName")
+ .setString("name", name)
+ .setParameter("token", token)
+ .list();
+ preventFurtherRepetitions(timers);
}
+ catch (HibernateException e) {
+ throw new JbpmException("could not delete timers by name '" + name +
"' for " + token, e);
+ }
}
public void deleteJobsForProcessInstance(ProcessInstance processInstance) {
- log.debug("deleting timers for "+processInstance);
- Query query =
session.getNamedQuery("JobSession.deleteTimersForProcessInstance");
- query.setParameter("processInstance", processInstance);
- int entityCount = query.executeUpdate();
- log.debug(entityCount+" remaining timers for "+processInstance+" were
deleted");
+ try {
+ // delete node execution jobs
+ int entityCount =
session.getNamedQuery("JobSession.deleteExecuteNodeJobsForProcessInstance")
+ .setParameter("processInstance", processInstance)
+ .executeUpdate();
+ log.debug("deleted " + entityCount + " execute-node-jobs for "
+ processInstance);
- log.debug("deleting execute-node-jobs for "+processInstance);
- query =
session.getNamedQuery("JobSession.deleteExecuteNodeJobsForProcessInstance");
- query.setParameter("processInstance", processInstance);
- entityCount = query.executeUpdate();
- log.debug(entityCount+" remaining execute-node-jobs for
"+processInstance+" were deleted");
+ // delete unowned timers
+ entityCount =
session.getNamedQuery("JobSession.deleteTimersForProcessInstance")
+ .setParameter("processInstance", processInstance)
+ .executeUpdate();
+ log.debug("deleted " + entityCount + " timers for " +
processInstance);
+
+ // prevent further repetitions
+ List<?> timers =
session.getNamedQuery("JobSession.findRepeatingTimersForProcessInstance")
+ .setParameter("processInstance", processInstance)
+ .list();
+ preventFurtherRepetitions(timers);
+ }
+ catch (HibernateException e) {
+ throw new JbpmException("could not delete jobs for " + processInstance,
e);
+ }
}
- public List<Job> findJobsWithOverdueLockTime(Date treshold) {
- Query query =
session.getNamedQuery("JobSession.findJobsWithOverdueLockTime");
- query.setDate("now", treshold);
- return CollectionUtil.checkList(query.list(), Job.class);
+ private static void preventFurtherRepetitions(List<?> timers) {
+ if (!timers.isEmpty()) {
+ for (Timer timer : CollectionUtil.checkList(timers, Timer.class)) {
+ timer.setRepeat(null);
+ }
+ log.debug("prevented further repetitions of " + timers);
+ }
}
- private static Long[] toObjectArray(long[] array) {
- final int length = array.length;
- Long[] objects = new Long[length];
- for (int i = 0; i < length; i++) {
- objects[i] = array[i];
+ public List<Job> findJobsWithOverdueLockTime(Date threshold) {
+ try {
+ List<?> jobs =
session.getNamedQuery("JobSession.findJobsWithOverdueLockTime")
+ .setDate("threshold", threshold)
+ .list();
+ return CollectionUtil.checkList(jobs, Job.class);
}
- return objects;
+ catch (HibernateException e) {
+ throw new JbpmException("could not find jobs with lock time over " +
threshold, e);
+ }
}
private static Log log = LogFactory.getLog(JobSession.class);
Modified:
jbpm3/trunk/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java
===================================================================
---
jbpm3/trunk/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java 2009-02-11
22:36:06 UTC (rev 3844)
+++
jbpm3/trunk/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java 2009-02-12
02:19:59 UTC (rev 3845)
@@ -20,7 +20,7 @@
int maxLockTime;
int lockBufferTime;
- boolean isActive = true;
+ volatile boolean isActive = true;
public LockMonitorThread(JbpmConfiguration jbpmConfiguration, int lockMonitorInterval,
int maxLockTime, int lockBufferTime) {
@@ -67,9 +67,9 @@
List<Job> overdueJobs = null;
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
- Date treshold = new Date(System.currentTimeMillis() - maxLockTime -
lockBufferTime);
+ Date threshold = new Date(System.currentTimeMillis() - maxLockTime -
lockBufferTime);
JobSession jobSession = jbpmContext.getJobSession();
- overdueJobs = jobSession.findJobsWithOverdueLockTime(treshold);
+ overdueJobs = jobSession.findJobsWithOverdueLockTime(threshold);
for (Job job : overdueJobs) {
log.debug("unlocking " + job + " owned by thread " +
job.getLockOwner());
job.setLockOwner(null);
Modified:
jbpm3/trunk/modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
===================================================================
---
jbpm3/trunk/modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml 2009-02-11
22:36:06 UTC (rev 3844)
+++
jbpm3/trunk/modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml 2009-02-12
02:19:59 UTC (rev 3845)
@@ -1,8 +1,7 @@
<?xml version="1.0"?>
-
<!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
@@ -15,14 +14,14 @@
from org.jbpm.graph.def.ProcessDefinition pd
]]>
</query>
-
+
<query name="GraphSession.NumberOfDeployedProcesses">
<![CDATA[
select count (distinct pd.name)
from org.jbpm.graph.def.ProcessDefinition pd
]]>
</query>
-
+
<query name="GraphSession.NumberOfActiveProcessInstances">
<![CDATA[
select count (pi.id)
@@ -30,7 +29,7 @@
where pi.end is null
]]>
</query>
-
+
<query name="GraphSession.findLatestProcessDefinitionQuery">
<![CDATA[
select pd
@@ -39,7 +38,7 @@
order by pd.version desc
]]>
</query>
-
+
<query name="GraphSession.findProcessDefinitionByNameAndVersion">
<![CDATA[
select pd
@@ -48,7 +47,7 @@
and pd.version = :version
]]>
</query>
-
+
<query name="GraphSession.findAllProcessDefinitions">
<![CDATA[
select pd
@@ -83,8 +82,8 @@
)
-->
</query>
-
- <query name="GraphSession.findAllProcessInstancesForADefinition">
+
+ <query name="GraphSession.findAllProcessInstancesForDefinition">
<![CDATA[
select pi
from org.jbpm.graph.exe.ProcessInstance as pi
@@ -92,7 +91,15 @@
order by pi.start desc
]]>
</query>
-
+
+ <query name="GraphSession.findAllProcessInstanceIdsForDefinition">
+ <![CDATA[
+ select pi.id
+ from org.jbpm.graph.exe.ProcessInstance as pi
+ where pi.processDefinition.id = :processDefinitionId
+ ]]>
+ </query>
+
<query name="GraphSession.findReferencingProcessStates">
<![CDATA[
select ps
@@ -139,7 +146,7 @@
order by pi.start desc
]]>
</query>
-
+
<query name="GraphSession.findSubProcessInstances">
<![CDATA[
select pi
@@ -149,7 +156,7 @@
order by pi.start desc
]]>
</query>
-
+
<query name="GraphSession.findTokensForProcessInNode">
<![CDATA[
select token
@@ -168,7 +175,7 @@
and token.node.name = :nodeName
]]>
</query>
-
+
<query name="GraphSession.findProcessInstanceByKey">
<![CDATA[
select pi
@@ -177,7 +184,7 @@
and pi.key = :key
]]>
</query>
-
+
<query name="GraphSession.findLogsForProcessInstance">
<![CDATA[
select pl
@@ -185,23 +192,14 @@
where pl.token.processInstance = :processInstance
]]>
</query>
-
-
- <query name="GraphSession.findTaskInstanceIdsForProcessInstance">
+
+ <query name="GraphSession.findTaskInstancesForProcessInstance">
<![CDATA[
- select ti.id
+ select ti
from org.jbpm.taskmgmt.exe.TaskInstance ti
- where ti.taskMgmtInstance.processInstance = :processInstance
+ where ti.processInstance = :processInstance
]]>
</query>
-
- <query name="GraphSession.deleteTaskInstancesById">
- <![CDATA[
- delete
- from org.jbpm.taskmgmt.exe.TaskInstance ti
- where ti.id in (:taskInstanceIds)
- ]]>
- </query>
<query name="GraphSession.deleteJobsForProcessInstance">
<![CDATA[
@@ -247,7 +245,7 @@
from org.jbpm.taskmgmt.def.Swimlane as swimlane
]]>
</query>
-
+
<!-- Logging -->
<!-- ########################### -->
@@ -259,7 +257,7 @@
order by pl.index
]]>
</query>
-
+
<!-- JobSession -->
<!-- ########################### -->
@@ -300,12 +298,12 @@
]]>
</query>
- <query name="JobSession.getFirstDueJobExlcMonitoredJobs">
+ <query name="JobSession.getFirstDueJobExcludingMonitoredJobs">
<![CDATA[
select job
from org.jbpm.job.Job as job
where ( (job.lockOwner is null) or (job.lockOwner = :lockOwner) )
- and job.id not in ( :jobIdsToIgnore )
+ and job.id not in ( :monitoredJobIds )
and job.retries > 0
and job.isSuspended = false
order by job.dueDate asc
@@ -333,20 +331,37 @@
delete from org.jbpm.job.Timer timer
where timer.token = :token
and timer.name = :name
- and (timer.lockOwner is null
- or timer.repeat is not null)
+ and timer.lockOwner is null
]]>
</query>
+ <query name="JobSession.findRepeatingTimersByName">
+ <![CDATA[
+ select timer
+ from org.jbpm.job.Timer timer
+ where timer.token = :token
+ and timer.name = :name
+ and timer.repeat is not null
+ ]]>
+ </query>
+
<query name="JobSession.deleteTimersForProcessInstance">
<![CDATA[
delete from org.jbpm.job.Timer timer
where timer.processInstance = :processInstance
- and (timer.lockOwner is null
- or timer.repeat is not null)
+ and timer.lockOwner is null
]]>
</query>
+ <query name="JobSession.findRepeatingTimersForProcessInstance">
+ <![CDATA[
+ select timer
+ from org.jbpm.job.Timer timer
+ where timer.processInstance = :processInstance
+ and timer.repeat is not null
+ ]]>
+ </query>
+
<query name="JobSession.deleteExecuteNodeJobsForProcessInstance">
<![CDATA[
delete from org.jbpm.job.ExecuteNodeJob job
@@ -354,7 +369,7 @@
and job.lockOwner is null
]]>
</query>
-
+
<query name="JobSession.findJobsByToken">
<![CDATA[
select job
@@ -363,10 +378,17 @@
]]>
</query>
+ <query name="JobSession.findJobsWithOverdueLockTime">
+ <![CDATA[
+ select job
+ from org.jbpm.job.Job as job
+ where job.lockTime > :threshold
+ ]]>
+ </query>
+
<!-- related to Tasks -->
<!-- ########################### -->
-
<query name="TaskMgmtSession.findTaskInstancesByActorId">
<![CDATA[
select ti
@@ -438,8 +460,7 @@
where ti.id in ( :taskInstanceIds )
]]>
</query>
-
-
+
<query name="TaskMgmtSession.findOpenTasksOfProcessInstance">
<![CDATA[
select ti
@@ -457,5 +478,5 @@
and task.taskNode.id = :taskNodeId
]]>
</query>
-
+
</hibernate-mapping>
Modified:
jbpm3/trunk/modules/core/src/test/java/org/jbpm/db/DeleteProcessInstanceDbTest.java
===================================================================
---
jbpm3/trunk/modules/core/src/test/java/org/jbpm/db/DeleteProcessInstanceDbTest.java 2009-02-11
22:36:06 UTC (rev 3844)
+++
jbpm3/trunk/modules/core/src/test/java/org/jbpm/db/DeleteProcessInstanceDbTest.java 2009-02-12
02:19:59 UTC (rev 3845)
@@ -15,18 +15,15 @@
+ " <state name='buy cheese' />"
+ "</process-definition>");
jbpmContext.deployProcessDefinition(processDefinition);
+ newTransaction();
try {
- newTransaction();
-
ProcessInstance processInstance = jbpmContext.newProcessInstance("make
fondue");
processInstance.signal();
processInstance = saveAndReload(processInstance);
-
jbpmContext.getGraphSession().deleteProcessInstance(processInstance);
newTransaction();
-
assertDeleted(processInstance);
}
finally {
@@ -44,18 +41,15 @@
+ " </task-node>"
+ "</process-definition>");
jbpmContext.deployProcessDefinition(processDefinition);
+ newTransaction();
try {
- newTransaction();
-
ProcessInstance processInstance = jbpmContext.newProcessInstance("make
fondue");
processInstance.signal();
processInstance = saveAndReload(processInstance);
-
jbpmContext.getGraphSession().deleteProcessInstance(processInstance);
newTransaction();
-
assertDeleted(processInstance);
}
finally {
@@ -81,18 +75,16 @@
+ " </process-state>"
+ "</process-definition>");
jbpmContext.deployProcessDefinition(makeFondue);
- try {
- newTransaction();
+ newTransaction();
+ try {
ProcessInstance processInstance = jbpmContext.newProcessInstance("make
fondue");
processInstance.signal();
processInstance = saveAndReload(processInstance);
-
jbpmContext.getGraphSession().deleteProcessInstance(processInstance);
newTransaction();
-
assertDeleted(processInstance.getRootToken().getProcessInstance());
assertDeleted(processInstance);
}
@@ -115,9 +107,8 @@
+ " <state name='bake bread' />"
+ "</process-definition>");
jbpmContext.deployProcessDefinition(makeFondue);
+ newTransaction();
try {
- newTransaction();
-
ProcessInstance processInstance = jbpmContext.newProcessInstance("make
fondue");
ContextInstance contextInstance = processInstance.getContextInstance();
contextInstance.setVariable("a", "asterix");
@@ -134,11 +125,9 @@
contextInstance.setVariable("b", "janneke", bread);
processInstance = saveAndReload(processInstance);
-
jbpmContext.getGraphSession().deleteProcessInstance(processInstance);
newTransaction();
-
assertDeleted(processInstance);
}
finally {
Modified:
jbpm3/trunk/modules/core/src/test/java/org/jbpm/graph/exe/SubProcessCancellationTest.java
===================================================================
---
jbpm3/trunk/modules/core/src/test/java/org/jbpm/graph/exe/SubProcessCancellationTest.java 2009-02-11
22:36:06 UTC (rev 3844)
+++
jbpm3/trunk/modules/core/src/test/java/org/jbpm/graph/exe/SubProcessCancellationTest.java 2009-02-12
02:19:59 UTC (rev 3845)
@@ -1,76 +1,67 @@
package org.jbpm.graph.exe;
-import java.util.Iterator;
-
import org.jbpm.db.AbstractDbTestCase;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.taskmgmt.exe.TaskInstance;
-public class SubProcessCancellationTest extends AbstractDbTestCase
+public class SubProcessCancellationTest extends AbstractDbTestCase
{
- public void testWithSubProcess()
+ public void testWithSubProcess()
{
- ProcessDefinition subProcess = ProcessDefinition.parseXmlString(
- "<process-definition name='sub'>" +
- " <start-state>" +
- " <transition to='wait' />" +
- " </start-state>" +
- " <task-node name='wait'>" +
- " <task>" +
- " <timer duedate='2 seconds' class='MyTimerClass'
/>" +
- " </task>" +
- " <transition to='end' />" +
- " </task-node>" +
- " <end-state name='end' />" +
- "</process-definition>"
- );
+ ProcessDefinition subProcess =
ProcessDefinition.parseXmlString("<process-definition
name='sub'>"
+ + " <start-state>"
+ + " <transition to='wait' />"
+ + " </start-state>"
+ + " <task-node name='wait'>"
+ + " <task>"
+ + " <timer duedate='2 seconds' class='MyTimerClass'
/>"
+ + " </task>"
+ + " <transition to='end' />"
+ + " </task-node>"
+ + " <end-state name='end' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(subProcess);
-
- ProcessDefinition superProcess = ProcessDefinition.parseXmlString(
- "<process-definition name='super'>" +
- " <start-state>" +
- " <transition to='subprocess' />" +
- " </start-state>" +
- " <process-state name='subprocess'>" +
- " <sub-process name='sub' />" +
- " <transition to='s'/>" +
- " </process-state>" +
- " <state name='s' />" +
- "</process-definition>"
- );
+
+ ProcessDefinition superProcess =
ProcessDefinition.parseXmlString("<process-definition
name='super'>"
+ + " <start-state>"
+ + " <transition to='subprocess' />"
+ + " </start-state>"
+ + " <process-state name='subprocess'>"
+ + " <sub-process name='sub' />"
+ + " <transition to='s'/>"
+ + " </process-state>"
+ + " <state name='s' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(superProcess);
-
+
+ newTransaction();
try
{
- newTransaction();
-
ProcessInstance pi = jbpmContext.newProcessInstanceForUpdate("super");
pi.signal();
-
+
ProcessInstance subPi = pi.getRootToken().getSubProcessInstance();
assertEquals("wait", subPi.getRootToken().getNode().getName());
-
- newTransaction();
- pi = jbpmContext.loadProcessInstance(pi.getId());
- subPi = pi.getRootToken().getSubProcessInstance();
+ pi = saveAndReload(pi);
pi.end();
pi.getTaskMgmtInstance().endAll();
- jbpmContext.save(pi);
+ pi = saveAndReload(pi);
assertTrue(pi.hasEnded());
+ subPi = pi.getRootToken().getSubProcessInstance();
assertTrue(subPi.hasEnded());
- Iterator iter = subPi.getTaskMgmtInstance().getTaskInstances().iterator();
- while (iter.hasNext()) {
- TaskInstance taskInstance = (TaskInstance) iter.next();
+
+ for (TaskInstance taskInstance : subPi.getTaskMgmtInstance().getTaskInstances())
+ {
assertFalse(taskInstance.isSignalling());
assertFalse(taskInstance.hasEnded());
}
}
finally
{
- jbpmContext.getGraphSession().deleteProcessDefinition(superProcess.getId());
- jbpmContext.getGraphSession().deleteProcessDefinition(subProcess.getId());
+ graphSession.deleteProcessDefinition(superProcess.getId());
+ graphSession.deleteProcessDefinition(subProcess.getId());
}
}
}
Modified: jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm2036/JBPM2036Test.java
===================================================================
--- jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm2036/JBPM2036Test.java 2009-02-11
22:36:06 UTC (rev 3844)
+++ jbpm3/trunk/modules/core/src/test/java/org/jbpm/jbpm2036/JBPM2036Test.java 2009-02-12
02:19:59 UTC (rev 3845)
@@ -5,65 +5,75 @@
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.ProcessInstance;
-import org.jbpm.graph.exe.Token;
/**
- * StaleObjectStateException when timer ends process
+ * StaleObjectStateException when repeating timer signals the token.
*
- *
https://jira.jboss.org/jira/browse/JBPM-2036
- *
+ * @see <a
href="https://jira.jboss.org/jira/browse/JBPM-2036">JBPM-203...
* @author Thomas.Diesler(a)jboss.com
* @since 11-Feb-2009
*/
-public class JBPM2036Test extends AbstractDbTestCase
+public class JBPM2036Test extends AbstractDbTestCase
{
- public void testTimerAction()
+ public void testTimerAction()
{
- if (true)
- {
- System.out.println("FIXME: [JBPM-2036] StaleObjectStateException when timer
ends process");
- return;
- }
-
ProcessDefinition pd = getProcessDefinition();
jbpmContext.deployProcessDefinition(pd);
+
newTransaction();
- try
+ try
{
- ProcessInstance pi = pd.createProcessInstance();
- Token tok = pi.getRootToken();
- tok.signal();
+ ProcessInstance pi = new ProcessInstance(pd);
+ pi.signal();
+ jbpmContext.save(pi);
+
+ processJobs(30000);
+
+ long piId = pi.getId();
+ assertTrue("expected process instance " + piId + " to have
ended",
+ jbpmContext.loadProcessInstance(piId).hasEnded());
+ assertEquals(1, TimerAction.getExecutionCount());
}
- finally {
- graphSession.deleteProcessDefinition(pd.getId());
+ finally
+ {
+ // TODO Timer -> Action -> Delegation cascade is broken somewhere
+ // graphSession.deleteProcessDefinition(pd.getId());
}
}
- private ProcessDefinition getProcessDefinition()
+ private ProcessDefinition getProcessDefinition()
{
- ProcessDefinition pd = ProcessDefinition.parseXmlString("<process-definition
name='jbpm2036' initial='start'>"
- + " <node name='start'>"
- + " <transition to='state1'/>"
- + " </node>"
- + " <state name='state1'>"
- + " <timer name='timer-to-end-with-repeat' duedate='1
second' repeat='5 seconds'>"
- + " <action class='" + TimerAction.class.getName() +
"' />"
+ return ProcessDefinition.parseXmlString("<process-definition
name='jbpm2036'>"
+ + " <start-state name='start'>"
+ + " <transition to='midway'/>"
+ + " </start-state>"
+ + " <state name='midway'>"
+ + " <timer name='chaos' duedate='1 second'
repeat='5 seconds'>"
+ + " <action class='"
+ + TimerAction.class.getName()
+ + "' />"
+ " </timer>"
+ " <transition to='end'/>"
+ " </state>"
+ " <end-state name='end' />"
+ "</process-definition>");
- return pd;
}
- public static class TimerAction implements ActionHandler
+ public static class TimerAction implements ActionHandler
{
+ private static int executionCount = 0;
+
private static final long serialVersionUID = 1L;
- public void execute(ExecutionContext executionContext) throws Exception
+ public void execute(ExecutionContext executionContext) throws Exception
{
- System.out.println("leaveNode");
- executionContext.leaveNode();
+ executionContext.leaveNode();
+ executionCount++;
}
+
+ public static int getExecutionCount()
+ {
+ return executionCount;
+ }
}
}