可以使用JPA实体作为流程变量, 并进行操作:
Activiti中JPA只支持符合以下要求的实体:
实体应该使用JPA注解进行配置, 支持字段和属性访问两种方式.@MappedSuperclass也要能够被使用
实体中应该有一个使用@Id注解的主键,不支持复合主键@EmbeddedId 和 @IdClass:
Id字段或者属性能够使用JPA规范支持的任意类型:
引擎必须有一个对EntityManagerFactory的引用才能够使用JPA的实体,这样可以通过配置引用或者提供一个持久化单元名称
作为变量的JPA实体将会被自动检测并进行相应的处理
使用jpaPersistenceUnitName配置:
<!-- 数据库的配置 -->
<property name="databaseSchemaUpdate" value="true" />
<property name="jdbcUrl" value="jdbc:h2:mem:JpaVariableTest;DB_CLOSE_DELAY=1000" />
<property name="jpaPersistenceUnitName" value="activiti-jpa-pu" />
<property name="jpaHandleTransaction" value="true" />
<property name="jpaCloseEntityManager" value="true" />
<!-- job executor configurations -->
<property name="jobExecutorActivate" value="false" />
<!-- mail server configurations -->
<property name="mailServerPort" value="5025" />
配置一个自定义的EntityManagerFactory,
也可以在编程式创建一个引擎时完成配置:
ProcessEngine processEngine = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResourceDefault()
.setJpaPersistenceUnitName("activiti-pu")
.buildProcessEngine();
配置的属性有:
jpaPersistenceUnitName: 使用持久化单元的名称:
jpaEntityManagerFactory: 一个实现了javax.persistence.EntityManagerFactory的bean的引用:
jpaHandleTransaction: 在被使用的EntityManager实例上,该标记表示流程引擎是否需要开始和提交或者回滚事务:
jpaCloseEntityManager: 该标记表示流程引擎是否应该关闭从 EntityManagerFactory获取的EntityManager的实例:
首先,需要创建一个基于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
variables.put("entityToUpdate", entityToUpdate);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("UpdateJPAValuesProcess", variables);
流程定义中的第一个节点是一个服务任务,将会调用entityToUpdate上的setValue方法,其实就是之前在启动流程实例时候设置的JPA变量并且将会从当前流程引擎的上下文关联的EntityManager中加载:
当完成服务任务时,流程实例将会停留在流程定义中定义的用户任务环节上:
// 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())
以查询某一JPA实体作为变量的ProcessInstances和Executions
在ProcessInstanceQuery和ExecutionQuery查询中仅仅variableValueEquals(name, entity) 支持JPA实体变量:
ProcessInstance result = runtimeService.createProcessInstanceQuery().variableValueEquals("entityToQuery", entityToQuery).singleResult();
JPASpringTest, 在activiti-spring-examples中:
流程定义步骤:
服务任务:
用户任务:
服务任务:
根据贷款申请实体变量approved的值,将利用唯一网关自动决定下一步该选择那一条路径:
当申请批准,流程结束
否则,一个额外的任务将会使用(发送拒绝信),这样就可以发送拒绝信手动通知客户
<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' />
上面的例子展示了JPA结合Spring和参数化方法表达式的强大优势 :所有的流程就不需要自定义java代码(Spring bean除外),大幅度的加快了流程部署
手机扫一扫
移动阅读更方便
你可能感兴趣的文章