我想为公用事务管理器(JpaTransactionManager
)进行hibernate和activiti,但我不能!我已阅读所有的互联网资源!听到的是一个简单的场景(它甚至不使用休眠!!):用常用TransactionManager管理Hibernate和Activiti
- 保存在任务变量 在任务执行#保存
- 可变
- 完成任务
方案的实施(在与@Transactional
注解弹簧Bean的方法):
@Component
public class TaskManager {
@Autowired TaskService taskService;
@Autowired RuntimeService runtimeService;
@Transactional
public void completeTask(CompleteTaskRequest request) {
Task task = taskService.createTaskQuery().taskId(request.getTaskId()).singleResult();
if (task == null) {
throw new ActivitiObjectNotFoundException("No task found");
}
taskService.setVariableLocal(task.getId(), "actionDisplayUrl", request.getActionDisplayUrl());
taskService.setVariableLocal(task.getId(), "actionSummaryUrl", request.getActionSummaryUrl());
runtimeService.setVariableLocal(task.getExecutionId(), "prevTaskId", task.getId());
taskService.complete(task.getId());
}
}
很明显:如果taskService.complete
抛出错误,整个交易应该rollbacked,因此,所有保存的变量应该rollbacked,和下面的测试情况下,应通过:
@Test
@Deployment(resources = "org.activiti.test/CompleteTaskTest.bpmn20.xml")
public void testCompleteTaskWithError() {
Map<String, Object> processVars = new HashMap<>();
processVars.put("error", true); // Causes throwing error in ScriptTaskListener
runtimeService.startProcessInstanceByKey("CompleteTaskTest", processVars);
Task task = taskService.createTaskQuery().taskName("Task 1").singleResult();
CompleteTaskRequest req = new CompleteTaskRequest();
req.setTaskId(task.getId());
req.setActionDisplayUrl("/actions/1234");
req.setActionSummaryUrl("/actions/1234/summary");
try {
taskManager.completeTask(req);
fail("An error expected!");
} catch(Exception e) {
}
// Check variables rollback
assertNull(taskService.getVariableLocal(task.getId(),"actionSummaryUrl"));
assertNull(taskService.getVariableLocal(task.getId(),"actionDisplayUrl"));
assertNull(runtimeService.getVariableLocal(task.getExecutionId(), "prevTaskId"));
}
但是失败了,变量致力于DB(未rollbacked)。
Spring上下文(使用org.springframework.orm.jpa.JpaTransactionManager
的事务管理器):
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="idGenerator" ref="idGenerator"/>
<property name="databaseSchemaUpdate" value="true" />
<property name="jpaEntityManagerFactory" ref="entityManagerFactory" />
<property name="jpaHandleTransaction" value="true" />
<property name="jpaCloseEntityManager" value="true" />
<property name="beans" ref="processEngineBeans" />
<property name="jobExecutorActivate" value="false" />
<property name="asyncExecutorEnabled" value="true" />
<property name="asyncExecutorActivate" value="true" />
</bean>
<aop:config proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="processEngineBeans" class="java.util.HashMap">
<constructor-arg index="0" type="java.util.Map">
<map>
</map>
</constructor-arg>
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
<bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
<bean id="idGenerator" class="org.activiti.engine.impl.persistence.StrongUuidGenerator" />
<bean id="activitiRule" class="org.activiti.engine.test.ActivitiRule">
<property name="processEngine" ref="processEngine" />
</bean>
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="packagesToScan" value="org.activiti.test" />
<property name="defaultDataSource" ref="dataSource" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect_resolvers">org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" >
<property name="proxyTargetClass" value="true" />
</bean>
版本:
- Activiti的版本:5.22.0
- DB:H2(生产与Oracle还测试)
我的配置有什么问题?
P.S.
- 测试项目上传here。
- 我也在alfresco forum问这个问题。
更新::
通过使用org.springframework.jdbc.datasource.DataSourceTransactionManager
代替org.springframework.orm.jpa.JpaTransactionManager
测试用例通过。但是现在我不能坚持JPA实体。
降票原因?? – united