Spring 使用Common TransactionManager管理Hibernate和Activiti

Spring 使用Common TransactionManager管理Hibernate和Activiti,spring,hibernate,jpa,activiti,transactionmanager,Spring,Hibernate,Jpa,Activiti,Transactionmanager,我想为hibernate和activiti使用一个通用事务管理器(JpaTransactionManager),但我不能!我已经阅读了所有的网络资源!Hear是一个简单的场景(它甚至不使用hibernate!!): 在任务中保存变量 在任务#执行中保存变量 完成任务 场景实现(在带有@Transactional注释的Springbean方法中): 很明显:如果taskService.complete抛出错误,那么整个事务都应该回滚,所以所有保存的变量都应该回滚,下面的测试用例应该通过: @Tes

我想为hibernate和activiti使用一个通用事务管理器(
JpaTransactionManager
),但我不能!我已经阅读了所有的网络资源!Hear是一个简单的场景(它甚至不使用hibernate!!):

  • 在任务中保存变量
  • 在任务#执行中保存变量
  • 完成任务
  • 场景实现(在带有
    @Transactional
    注释的Springbean方法中):

    很明显:如果
    taskService.complete
    抛出错误,那么整个事务都应该回滚,所以所有保存的变量都应该回滚,下面的测试用例应该通过:

    @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"));
    }
    
    版本:

    • Activiti版本:5.22.0
    • DB:h2(也在生产中与Oracle一起测试)
    我的配置有什么问题

    附言

    • 测试项目已上载
    • 我刚才也提过这个问题
    更新::


    通过使用
    org.springframework.jdbc.datasource.DataSourceTransactionManager
    而不是
    org.springframework.orm.jpa.JpaTransactionManager
    测试用例通过。但现在我无法持久化JPA实体。

    通过解决MyBatis(JDBC)和Hibernate(JPA)之间的冲突,问题得到了解决:

    jpaVendorAdapter
    属性应添加到
    entityManagerFactory
    bean:

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

    有关更多详细信息,请参阅的答案。

    否决投票理由??
    <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>
    
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    
    <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>