- Chapter 1. Introduction 介绍
- Chapter 2. Getting Started
- Chapter 3. Configuration
- Creating a ProcessEngine 创建 ProcessEngine
- ProcessEngineConfiguration bean
- Database configuration 数据库配置
- JNDI Datasource Configuration 数据源配置
- Supported databases 支持的数据库
- Creating the database tables 创建数据库表
- Database table names explained 理解数据库表名字
- Database upgrade 数据库升级
- Job Executor and Async Executor (since version 5.17.0)
- Job executor activation 启用 Job executor
- Async executor activation 启用 Async executor
- Mail server configuration 配置邮件服务器
- History configuration 配置历史
- Exposing configuration beans in expressions and scripts 在表达式和脚本中暴露配置
- Deployment cache configuration 配置部署缓存
- Logging 日志
- Mapped Diagnostic Contexts 映射诊断上下文
- Event handlers 事件处理
- Chapter 4. The Activiti API
- Chapter 5. Spring integration 集成 Spring
- Chapter 6. Deployment
- Chapter 7. BPMN 2.0 Introduction
- Chapter 8. BPMN 2.0 Constructs 关于 BPMN 2.0 架构
- Chapter 9. Forms 表单
- Chapter 10. JPA
- Chapter 11. History 历史
- Chapter 12. Eclipse Designer
- Chapter 13. Activiti Explorer
- Chapter 14. Activiti Modeler
- Chapter 15. REST API
- Chapter 16. CDI integration 集成 CDI
- Chapter 17. LDAP integration 集成 LDAP
- Chapter 18. Advanced 高级
- Hooking into process parsing 监听流程解析
- UUID id generator for high concurrency 高并发的 UUID 生成器
- Multitenancy 多租户
- Execute custom SQL 执行自定义 SQL
- Advanced Process Engine configuration with a ProcessEngineConfigurator 用 ProcessEngineConfigurator 实现高级引擎配置
- Advanced query API seamless switching between runtime and historic task querying 高级查询 API-运行时无缝任务切换和历史任务查询
- Custom identity management by overriding standard SessionFactory 通过重写标准的 SessionFactory 实现自定义身份的管理
- Enable safe BPMN 2.0 xml 启用安全的 BPMN 2.0 xml
- Event logging Experimental 事件日志-实验
- Introduction 介绍
- CrystalBall inside 内部
- History analysis 历史分析
10.3. Usage 用法
10.3.1. 简单例子
使用 JPA 变量的例子可以在 JPAVariableTest 中找到。我们将会一步一步的解释 JPAVariableTest.testUpdateJPAEntityValues
。
首先,我们需要创建一个基于 META-INF/persistence.xml
的 EntityManagerFactory 作为我们的持久化单元。它包含持久化单元中所有的类和一些供应商特定的配置。
我们将使用一个简单的实体作为测试,其中包含有一个 id 和 String
类型的 value 属性,这也将会被持久化。在允许测试之前,我们创建一个实体并且保存它。
@Entity(name = "JPA_ENTITY_FIELD")
public class FieldAccessJPAEntity {
@Id
@Column(name = "ID_")
private Long id;
private String value;
public FieldAccessJPAEntity() {
// Empty constructor needed for 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);
在我们的流程定义的第一个节点包含一个 serviceTask
将调用方法 在 entityToUpdate
上 setValue
,它解析为 JPA 变量,我们启动流程实例并将从相关联的当前引擎的上下文“EntityManager”进行加载。
<serviceTask id='theTask' name='updateJPAEntityTask'
activiti:expression="${entityToUpdate.setValue('updatedValue')}" />
当 service-task 完成后,流程实例等在流程定义中定义的 userTask,这使我们能够检查流程实例。在这一点上,EntityManager 已刷新并更改到实体已经被推到数据库。当我们得到变量 entityToUpdate 值时,它再次加载,我们得到实体,并将实体中的属性 value
设置到 updatedValue
。
// Servicetask in process 'UpdateJPAValuesProcess' should have set value on entityToUpdate.
Object updatedEntity = runtimeService.getVariable(processInstance.getId(), "entityToUpdate");
assertTrue(updatedEntity instanceof FieldAccessJPAEntity);
assertEquals("updatedValue", ((FieldAccessJPAEntity)updatedEntity).getValue());
10.3.2. 查询 JPA 处理变量
可以查询 ProcessInstances
和 Execution
包含 JPA 实体作为变量值。注意 只有 在 ProcessInstanceQuery 和 ExecutionQuery , variableValueEquals(name, entity)
是支持 JPA 实体的 。 方法 variableValueNotEquals
, variableValueGreaterThan
, variableValueGreaterThanOrEqual
, variableValueLessThan
和 variableValueLessThanOrEqual
不支持,并且当一个 JPA 实体传递作为值时,会抛出 ActivitiException
。
ProcessInstance result = runtimeService.createProcessInstanceQuery()
.variableValueEquals("entityToQuery", entityToQuery).singleResult();
10.3.3. 高级例子:使用 Spring bean 和 JPA
JPASpringTest 例子可以在 activiti-spring-examples 中找到。它的使用场景如下:
- 存在一个使用 JPA 实体的 Spring bean,用于存储贷款请求。
- 使用 Activiti,我们可以利用那些由现有的 bean 获得的已有的实体,并将其作为变量在流程中使用。 流程是按以下步骤进行定义的:
- 服务任务,利用已有的 LoanRequestBean 使用启动流程时接收的变量(比如,可以来源于开始的表单)来创建新的 LoanRequest。使用 activiti:resultVariable(它以一个变量来存储表达式结果)将创建出来的实体以变量进行存储。
- 用户任务,让经理查看请求,批准/不批准,结果存储到一个 boolean 类型的变量 approvedByManager 上。
- 服务任务,用来更新贷款请求实体以使该实体与流程同步。
- 根据实体属性 approved 的值,利用排他分支来决定下一步选择哪条路径:当请求被批准时,流程将结束;否则,会另有一个任务(发送拒绝信),这样就可以由拒绝信手动地通知用户了。
请注意此流程不包含任何表单,所以其只用于单元测试
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="taskAssigneeExample"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="org.activiti.examples">
<process id="LoanRequestProcess" name="Process creating and handling loan request">
<startEvent id='theStart' />
<sequenceFlow id='flow1' sourceRef='theStart' targetRef='createLoanRequest' />
<serviceTask id='createLoanRequest' name='Create loan request'
activiti:expression="${loanRequestBean.newLoanRequest(customerName, amount)}"
activiti:resultVariable="loanRequest"/>
<sequenceFlow id='flow2' sourceRef='createLoanRequest' targetRef='approveTask' />
<userTask id="approveTask" name="Approve request" />
<sequenceFlow id='flow3' sourceRef='approveTask' targetRef='approveOrDissaprove' />
<serviceTask id='approveOrDissaprove' name='Store decision'
activiti:expression="${loanRequest.setApproved(approvedByManager)}" />
<sequenceFlow id='flow4' sourceRef='approveOrDissaprove' targetRef='exclusiveGw' />
<exclusiveGateway id="exclusiveGw" name="Exclusive Gateway approval" />
<sequenceFlow id="endFlow1" sourceRef="exclusiveGw" targetRef="theEnd">
<conditionExpression xsi:type="tFormalExpression">${loanRequest.approved}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="endFlow2" sourceRef="exclusiveGw" targetRef="sendRejectionLetter">
<conditionExpression xsi:type="tFormalExpression">${!loanRequest.approved}</conditionExpression>
</sequenceFlow>
<userTask id="sendRejectionLetter" name="Send rejection letter" />
<sequenceFlow id='flow5' sourceRef='sendRejectionLetter' targetRef='theOtherEnd' />
<endEvent id='theEnd' />
<endEvent id='theOtherEnd' />
</process>
</definitions>
虽然上面的例子很简单,但确实展示出了结合 Spring 和参数化方法表达式来使用 JPA 的强大。此流程根本不需要定制 java 代码(当然了,除 Spring bean 外),大大加速了部署
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论