- 1. 简介
- 2. 开始
- 3. 配置
- 4. Flowable API
- 5. 集成 Spring
- 6. 部署
- 7. BPMN 2.0 介绍
- 8. BPMN 2.0 结构
- 9. 表单
- 10. JPA
- 11. 历史
- 12. 身份管理
- 13. Eclipse Designer
- 14. Flowable UI 应用
- 15. REST API
- 16. 集成 CDI
- 17. 集成 LDAP
- 18. 高级
- 19. 工具
10.3. 使用
10.3.1. 简单示例
可以在Flowable源代码的JPAVariableTest中找到使用JPA变量的例子。下面逐步解释JPAVariableTest.testUpdateJPAEntityValues
。
首先,基于META-INF/persistence.xml
为持久化单元创建EntityManagerFactory。包括需要包含在持久化单元内的类及一些(数据库)厂商特定配置。
在这个测试里使用的是简单实体,包括id以及一个String
值参数。在运行测试前,先创建一个实体并保存。
@Entity(name = "JPA_ENTITY_FIELD")
public class FieldAccessJPAEntity {
@Id
@Column(name = "ID_")
private Long id;
private String value;
public FieldAccessJPAEntity() {
// JPA需要的空构造方法
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
启动一个新的流程实例,将这个实体加入变量。与其他变量一样,它们都会在引擎中持久化存储。当下一次请求这个变量时,将会根据类及Id,从EntityManager
载入。
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("entityToUpdate", entityToUpdate);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
"UpdateJPAValuesProcess", variables);
流程定义的第一个节点是服务任务
,将调用entityToUpdate
上的setValue
方法。entityToUpdate
将解析为之前启动流程实例时设置的JPA变量,并使用当前引擎的上下文中关联的EntityManager
载入。
<serviceTask id='theTask' name='updateJPAEntityTask'
flowable:expression="${entityToUpdate.setValue('updatedValue')}" />
当服务任务完成时,流程实例在流程定义中的用户任务处等待,以便我们可以查看流程实例。在这时,EntityManager
已经刷入,对实体的修改也已经存入数据库。当获取entityToUpdate
变量的值时,将重新载入实体。所以可以得到value
参数设置为updatedValue
的实体。
// 流程'UpdateJPAValuesProcess'中的服务任务已经设置了entityToUpdate的值。
Object updatedEntity = runtimeService.getVariable(processInstance.getId(), "entityToUpdate");
assertTrue(updatedEntity instanceof FieldAccessJPAEntity);
assertEquals("updatedValue", ((FieldAccessJPAEntity)updatedEntity).getValue());
10.3.2. 查询JPA流程变量
可以查询以特定JPA实体作为变量值的流程实例
与执行
。请注意ProcessInstanceQuery
与ExecutionQuery
中,只有variableValueEquals(name, entity)
方法支持JPA实体查询。而variableValueNotEquals
、variableValueGreaterThan
、variableValueGreaterThanOrEqual
、variableValueLessThan
与variableValueLessThanOrEqual
等方法都不支持JPA,并会在值传递为JPA实体时,抛出FlowableException
。
ProcessInstance result = runtimeService.createProcessInstanceQuery()
.variableValueEquals("entityToQuery", entityToQuery).singleResult();
10.3.3. 使用Spring bean与JPA的高级示例
可以在flowable-spring-examples
中找到高级用法的示例——JPASpringTest
。它描述了一个简单的用例:
使用一个已有的Spring bean及已定义的JPA实体,用于存储贷款申请。
Flowable通过该bean获取该实体,并将其用作流程中的变量。流程定义如下步骤:
使用
LoanRequestBean
,并使用启动流程时(从启动表单)接收的变量创建LoanRequest(贷款申请)实体的服务任务。使用flowable:resultVariable
将表达式结果,即所创建的实体存储为流程变量。经理用于审核并批准/驳回申请的用户任务,并将审核结论存储为boolean变量
approvedByManager
。更新贷款申请实体的服务任务,使实体与流程同步。
使用一个排他网关,依据
approved
实体参数的值选择下一步采用哪条路径:若申请被批准,结束流程;否则,生成一个额外任务(Send rejection letter 发送拒信),以便客户可以收到拒信得到通知。
请注意这个流程只用于单元测试,而不包含任何表单。
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flowable="http://flowable.org/bpmn"
targetNamespace="org.flowable.examples">
<process name="Process creating and handling loan request">
<startEvent id='theStart' />
<sequenceFlow id='flow1' sourceRef='theStart' targetRef='createLoanRequest' />
<serviceTask id='createLoanRequest' name='Create loan request'
flowable:expression="${loanRequestBean.newLoanRequest(customerName, amount)}"
flowable:resultVariable="loanRequest"/>
<sequenceFlow id='flow2' sourceRef='createLoanRequest' targetRef='approveTask' />
<userTask name="Approve request" />
<sequenceFlow id='flow3' sourceRef='approveTask' targetRef='approveOrDissaprove' />
<serviceTask id='approveOrDissaprove' name='Store decision'
flowable:expression="${loanRequest.setApproved(approvedByManager)}" />
<sequenceFlow id='flow4' sourceRef='approveOrDissaprove' targetRef='exclusiveGw' />
<exclusiveGateway name="Exclusive Gateway approval" />
<sequenceFlow sourceRef="exclusiveGw" targetRef="theEnd">
<conditionExpression xsi:type="tFormalExpression">${loanRequest.approved}</conditionExpression>
</sequenceFlow>
<sequenceFlow sourceRef="exclusiveGw" targetRef="sendRejectionLetter">
<conditionExpression xsi:type="tFormalExpression">${!loanRequest.approved}</conditionExpression>
</sequenceFlow>
<userTask name="Send rejection letter" />
<sequenceFlow id='flow5' sourceRef='sendRejectionLetter' targetRef='theOtherEnd' />
<endEvent id='theEnd' />
<endEvent id='theOtherEnd' />
</process>
</definitions>
尽管上面的例子很简单,但也展示了JPA与Spring结合,以及带参数方法表达式的威力。这个流程本身完全不需要写Java代码(当然还是需要写Spring bean),大幅加速了开发。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论