2017-06-21 25 views
1

我想为公用事务管理器(JpaTransactionManager)进行hibernate和activiti,但我不能!我已阅读所有的互联网资源!听到的是一个简单的场景(它甚至不使用休眠!!):用常用TransactionManager管理Hibernate和Activiti

  1. 保存在任务变量
  2. 在任务执行#保存
  3. 可变
  4. 完成任务

方案的实施(在与@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.

更新::

通过使用org.springframework.jdbc.datasource.DataSourceTransactionManager代替org.springframework.orm.jpa.JpaTransactionManager测试用例通过。但是现在我不能坚持JPA实体。

+0

降票原因?? – united

回答

0

问题是由解决的MyBatis(JDBC)和Hibernate(JPA)之间的冲突解决:

jpaVendorAdapter属性添加到entityManagerFactory豆:

<property name="jpaVendorAdapter"> 
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
</property> 

所以entityManagerFactory豆应该是这样的:

<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="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
    </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> 

欲了解更多详情,请参阅this question的回答。

相关问题