這篇文章主要講解了“如何配置工作流引擎Activiti集成JPA持久化保存流程數據”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何配置工作流引擎Activiti集成JPA持久化保存流程數據”吧!
可以使用JPA實體作為流程變量, 并進行操作:
基于流程變量更新已有的JPA實體,可以在用戶任務的表單中填寫或者由服務任務生成
重用已有的領域模型,不需要編寫顯示的服務獲取實體或者更新實體的值
根據已有實體的屬性做出判斷(網關即分支聚合)
Activiti中JPA只支持符合以下要求的實體:
Id字段或者屬性能夠使用JPA規范支持的任意類型:
原生態數據類型和他們的包裝類型(Boolean除外)
String
BigInteger
BigDecimal
java.util.Date
java.sql.Date
實體應該使用JPA注解進行配置, 支持字段和屬性訪問兩種方式.@MappedSuperclass也要能夠被使用
實體中應該有一個使用@Id注解的主鍵,不支持復合主鍵@EmbeddedId 和 @IdClass:
引擎必須有一個對EntityManagerFactory的引用才能夠使用JPA的實體,這樣可以通過配置引用或者提供一個持久化單元名稱
作為變量的JPA實體將會被自動檢測并進行相應的處理
使用jpaPersistenceUnitName配置:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration"> <!-- 數據庫的配置 --> <property name="databaseSchemaUpdate" value="true" /> <property name="jdbcUrl" value="jdbc:h3: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" /> </bean>
配置一個自定義的EntityManagerFactory,
這里使用了OpenJPA實體管理器
該代碼片段僅僅包含與例子相關的beans,去掉了其他beans.
OpenJPA實體管理的完整并可以使用的例子可以在activiti-spring-examples(/activiti-spring/src/test/java/org/activiti/spring/test/jpa/JPASpringTest.java) 中找到
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitManager" ref="pum"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"> <property name="databasePlatform" value="org.apache.openjpa.jdbc.sql.H2Dictionary" /> </bean> </property> </bean> <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="databaseSchemaUpdate" value="true" /> <property name="jpaEntityManagerFactory" ref="entityManagerFactory" /> <property name="jpaHandleTransaction" value="true" /> <property name="jpaCloseEntityManager" value="true" /> <property name="jobExecutorActivate" value="false" /> </bean>
也可以在編程式創建一個引擎時完成配置:
ProcessEngine processEngine = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResourceDefault()
.setJpaPersistenceUnitName("activiti-pu")
.buildProcessEngine();配置的屬性有:
jpaPersistenceUnitName: 使用持久化單元的名稱:
要確保該持久化單元在類路徑下是可用的,默認的路徑是 /META-INF/persistence.xml
要么使用jpaEntityManagerFactory要么或者是jpaPersistenceUnitName
jpaEntityManagerFactory: 一個實現了javax.persistence.EntityManagerFactory的bean的引用:
將被用來加載實體并且刷新更新
要么使用jpaEntityManagerFactory要么或者是jpaPersistenceUnitName
jpaHandleTransaction: 在被使用的EntityManager實例上,該標記表示流程引擎是否需要開始和提交或者回滾事務:
當使用Java事務API(JTA) 時,設置為false
jpaCloseEntityManager: 該標記表示流程引擎是否應該關閉從 EntityManagerFactory獲取的EntityManager的實例:
當EntityManager是由容器管理的時候需要設置為false: 當使用并不是單一事務作用域的擴展持久化上下文的時候
首先,需要創建一個基于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);流程定義中的第一個節點是一個服務任務,將會調用entityToUpdate上的setValue方法,其實就是之前在啟動流程實例時候設置的JPA變量并且將會從當前流程引擎的上下文關聯的EntityManager中加載:
<serviceTask id='theTask' name='updateJPAEntityTask' activiti:expression="${entityToUpdate.setValue('updatedValue')}" />當完成服務任務時,流程實例將會停留在流程定義中定義的用戶任務環節上:
可以查看該流程實例
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())以查詢某一JPA實體作為變量的ProcessInstances和Executions
在ProcessInstanceQuery和ExecutionQuery查詢中僅僅variableValueEquals(name, entity) 支持JPA實體變量:
[variableValueNotEquals],[variableValueGreaterThan],[variableValueGreaterThanOrEqual],[variableValueLessThan],[variableValueLessThanOrEqual]不被支持并且傳遞JPA實體值的時候會拋出一個ActivitiException
ProcessInstance result = runtimeService.createProcessInstanceQuery().variableValueEquals("entityToQuery", entityToQuery).singleResult();JPASpringTest, 在activiti-spring-examples中:
已經存在了一個使用JPA實體的Spring-bean, 用來存儲貸款申請
使用Activiti,可以通過已經存在的bean獲取已經使用的實體,并使用它作為變量用于流程中
流程定義步驟:
當申請批準,流程結束
否則,一個額外的任務將會使用(發送拒絕信),這樣就可以發送拒絕信手動通知客戶 
更新貸款申請實體,因此該實體與流程保持同步
允許經理查看貸款申請,并填入審批意見(同意/不同意)
審批意見將作為一個boolean變量approvedByManager進行存儲
創建一個新的貸款申請,使用已經存在的LoanRequestBean接受啟動流程時候的變量(來自流程啟動時候的表單)
使用activiti:resultVariable(作為一個變量對表達式返回的結果進行存儲)將創建出來的實體作為變量進行存儲
服務任務:
用戶任務:
服務任務:
根據貸款申請實體變量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>感謝各位的閱讀,以上就是“如何配置工作流引擎Activiti集成JPA持久化保存流程數據”的內容了,經過本文的學習后,相信大家對如何配置工作流引擎Activiti集成JPA持久化保存流程數據這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。