Jbpm工做流開發過程當中的一些知識點總結,方便之後開發使用!java
目錄:mysql
1、工做流框架的搭建spring
2、工做流框架的流程開發sql
一、管理流程定義數據庫
①部署流程定義apache
②查詢流程定義api
③刪除流程定義tomcat
④獲取部署對象中的文件資源內容session
⑤ 獲取流程圖中某活動的座標app
二、執行流程實例
①啓動流程實例
②向後執行一步
③查詢任務
④完成任務
⑤拾取任務
⑥獲取流程中的變量
3、Jbpm和spring整合
注意區分Deployment與ProcessDefinition
String deploymentId = processEngine.getRepositoryService()
.createDeployment()
.addResourceFromClasspath("process/test.jpdl.xml")
.addResourceFromClasspath("process/test.png")
.deploy();
String deploymentId = processEngine.getRepositoryService()
.createDeployment()
.addResourcesFromZipInputStream(zipInputStream)
.deploy();
1, .addResourceFromClasspath(resource); 能夠調用屢次以添加多個文件。文件重複添加也不會報錯。
2, .addResourceFromInputStream(resourceName, inputStream)添加一個文件(使用InputStream)
3, .addResourcesFromZipInputStream(zipInputStream)添加多個文件,裏面也能夠有文件夾。
4, 以上方法能夠在一塊兒調用。
repositoryService.deleteDeployment(deploymentId);
repositoryService.deleteDeploymentCascade(deploymentId);
關聯:關聯的流程實例,就是流程定義中執行過的那些實例【已經放到了歷史表中,級聯刪除的就是同時刪除那些執行過了的實例】,
RepositoryService.createProcessDefinitionQuery()
// 1,構建查詢
ProcessDefinitionQuery pdQuery = processEngine.getRepositoryService()
.createProcessDefinitionQuery()//
.orderAsc(ProcessDefinitionQuery.PROPERTY_NAME)//
.orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION);
// 2,查詢出總數量與數據列表
long count = pdQuery.count();
List<ProcessDefinition> list = pdQuery.page(0, 100).list();// 分頁:取出前100條記錄
// 3,顯示結果
System.out.println(count);
for (ProcessDefinition pd : list) {
System.out.println("id=" + pd.getId()//
+ ",deploymentId=" + pd.getDeploymentId()//
+ ",name=" + pd.getName()//
+ ",version=" + pd.getVersion()//
+ ",key=" + pd.getKey()); //
}
// 1,查詢,按version升序排序,則最大版本排在最後面
List<ProcessDefinition> all = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)
.list();
// 2,過濾出全部不一樣Key的最新版本(由於最大版本在最後面)
Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>(); // map的key是流程定義的key,map的vlaue是流程定義對象
for (ProcessDefinition pd : all) {
map.put(pd.getKey(), pd);
}
Collection<ProcessDefinition> result = map.values();
// 3,顯示結果
for (ProcessDefinition pd : result) {
System.out.println("deploymentId=" + pd.getDeploymentId()//
+ ",\t id=" + pd.getId()// 流程定義的id,格式:{key}-{version}
+ ",\t name=" + pd.getName()
+ ",\t key=" + pd.getKey()
+ ",\t version=" + pd.getVersion());
}
// 資源的名稱,就是 jbpm4_lob 表中的 NAME_ 列表值
String deploymentId = "90001";
String resourceName = "test.png";
InputStream in = processEngine.getRepositoryService()
.getResourceAsStream(deploymentId, resourceName);
String processDefinitionId = "test-1"; // 流程定義的id
String activityName = "start1"; // 活動的名稱
ActivityCoordinates c = processEngine.getRepositoryService()
.getActivityCoordinates(processDefinitionId, activityName);
System.out.println("x=" + c.getX()
+ ",y=" + c.getY()
+ ",width=" + c.getWidth()
+ ",height=" + c.getHeight());
說明:流程實例建立後,直接就到開始活動後的第一個活動,不會在開始活動停留。
ProcessInstance pi = processEngine.getExecutionService()
.startProcessInstanceByKey(processDefinitionKey);
// 準備流程變量
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("申請人", "張三");
variables.put("報銷金額", 1000.00);
// 啓動流程實例,並設置一些流程變量
ProcessInstance pi = processEngine.getExecutionService()
.startProcessInstanceByKey(processDefinitionKey, variables);
processEngine.getExecutionService().signalExecutionById(executionId);
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("審批結果", "贊成");
processEngine.getExecutionService()
.signalExecutionById(executionId, variables);
String outcome= "to end1";
processEngine.getExecutionService()
.signalExecutionById(executionId, outcome);
String outcome= "to end1";
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("審批結果", "贊成");
processEngine.getExecutionService()
.signalExecutionById(executionId, outcome, variables);
方式1:TaskService.findPersonalTasks(userId);
方式2:List<Task> list = taskService.createTaskQuery()
.assignee(userId)
.list();
// 顯示任務信息
for (Task task : taskList) {
System.out.println("id=" + task.getId()// 任務的id
+ ",name=" + task.getName()// 任務的名稱
+ ",assignee=" + task.getAssignee()// 任務的辦理人
+ ",createTime=" + task.getCreateTime() // 任務的建立(生成)的時間
+ ",executionId=" + task.getExecutionId());// 任務所屬流程實例的id
}
方式1: taskService.findGroupTasks(userId);
方式2: List<Task> list = processEngine.getTaskService()//
.createTaskQuery()//
.candidate(userId)//
.list();
String taskId = "420001";
processEngine.getTaskService().completeTask(taskId);
processEngine.getTaskService().completeTask(taskId, outcome);
processEngine.getTaskService().completeTask(taskId, outcome, variables);
String taskId = "420001";
// 1,設置爲false表明:辦理完任務後不向後移動(默認爲true)
TaskImpl taskImpl = (TaskImpl) processEngine
.getTaskService().getTask(taskId);
taskImpl.setSignalling(false);
// 2,辦理完任務
processEngine.getTaskService().completeTask(taskId);
1, TaskService.takeTask(taskId, userId),拾取組任務到我的任務列表中,若是任務有assignee,則會拋異常。
2, processEngine.getTaskService().assignTask(taskId, userId),轉交任務給其餘人,(若是任務有assignee,則執行這個方法表明從新分配。也能夠把assignee設爲null表示組任務沒有人辦理了)
ExecutionService.setVariable(executionId, name, value);
Object obj = executionService.getVariable(executionId, "請假人");
TaskService.setVariables(taskId, variables); // 一次設置多個變量
Object obj = executionService.getVariable(executionId, "請假人");
7.2. Variable types
jBPM supports following Java types as process variables:
java.lang.String
java.lang.Long
java.lang.Double
java.util.Date
java.lang.Boolean
java.lang.Character
java.lang.Byte
java.lang.Short
java.lang.Integer
java.lang.Float
byte[] (byte array)
char[] (char array)
hibernate entity with a long id
hibernate entity with a string id
serializable
For persistence of these variable, the type of the variable is checked in the order of this list. The first match will determine how the variable is stored.
String processInstanceId = "test.10001";
processEngine.getExecutionService()
.endProcessInstance(processInstanceId, ProcessInstance.STATE_ENDED);
1,刪除配置:<import resource="jbpm.tx.hibernate.cfg.xml" />
2,增長配置:<import resource="jbpm.tx.spring.cfg.xml" />
<!-- 配置ProcessEngine(整合jBPM4) -->
<!-- jbpmCfg是相對於classpath的相對路徑,默認值爲jbpm.cfg.xml -->
<bean id="springHelper"
class="org.jbpm.pvm.internal.processengine.SpringHelper">
<property name="jbpmCfg" value="jbpm.cfg.xml"></property>
</bean>
<bean id="processEngine" factory-bean="springHelper"
factory-method="createProcessEngine" />
@Test // 測試ProcessEngine
public void testProcessEngine() {
ProcessEngine processEngine = (ProcessEngine)ac.getBean("processEngine");
Assert.assertNotNull(processEngine);
}
若是作了JBPM4.4與Spring整合(使用了jbpm.tx.spring.cfg.xml),則在程序中就必定要使用Spring注入ProcessEngine,千萬不能使用Configuration.getProcessEngine()生成ProcessEngine,由於這時內部的代碼有如下邏輯:若是整合了Spring但沒有ApplicationContext,就默認讀取applicationContext.xml建立ApplicationContext實例並從中獲取名爲」ProcessEngine」的對象。而這時若是把pe = Configuration.getProcessEngine()寫成某Spring中管理的bean的初始化代碼,就會有無限循環,不停的建立ApplicationContext了!
1, 修改 jbpm.tx.hibernate.cfg.xml
a) 不讓jBPM自行管理事務:去掉<standard-transaction-interceptor />
b) 讓Jbpm使用SessionFactory.getCurrentSession():修改成 <hibernate-session current="true" />
2, 配置可使用SessionFactory.getCurrentSession(),在jbpm.hibernate.cfg.xml 中配置:<property name="hibernate.current_session_context_class">thread</property>
3, 要使用同一個SessionFactory,且都要使用 SessionFactory.getCurrentSession() 獲取 Session:
a) 同一個SessionFactory:SessionFactory sf = processEngine.get(SessionFactory.class)
b) 在 BaseDaoImpl 中增長:
4, 統一的打開與提交或回滾事務:使用 OpenSessionInViewFilter 控制事務。
at org.apache.jsp.WEB_002dINF.jsp.UserAction.loginUI_jsp._jspInit(loginUI_jsp.java:39)
at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)
at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
... 40 more
說明:緣由是Jbpm的juel.jar, juel-engine.jar, juel-impl.jar包和Tomcat6.0中的el-api.jar包衝突了。
有三個解決辦法:
1,方法一:在MyEclipse的Preferences -> MyEclipse -> Application Servers -> Tomcat -> .. -> Paths 中配置 Append to classpath,選中 juel.jar, juel-engine.jar, juel-impl.jar 這三個jar包就能夠了。
2,方法二:將 juel.jar, juel-engine.jar, juel-impl.jar 這三個包複製到tomcat6下 lib/ 中,並刪除原來的el-api.jar,
切記還要把工程中 WEB-INF\lib 下的 juel.jar, juel-engine.jar, juel-impl.jar 刪除,否則仍是要衝突。
3,方法三:換成tomcat5.5,就沒有問題了。
com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`itcastoa_20100909/jbpm4_execution`, CONSTRAINT `FK_EXEC_INSTANCE` FOREIGN KEY (`INSTANCE_`) REFERENCES `jbpm4_execution` (`DBID_`))
解決辦法:把方言設爲 MySQL5InnoDBDialect,不能是 MySQLDialect。