2017-06-21 3 views
1

hibernateとactivitiに共通のトランザクションマネージャ(JpaTransactionManager)を使用したいと思いますが、できません!そして私はそれのためにすべてのインターネットリソースを読んだ!聞く簡単なシナリオである(でも、休止状態は使用しません!!):共通のトランザクションマネージャを使用してHibernateとActivitiを管理する

  1. 保存タスク#実行中のタスク
  2. 内の変数の保存変数
  3. コンプリートタスク

シナリオの実装(中@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()); 
    } 
} 

それは明らかだ:場合がエラーをスローし、トランザクション全体がそう、保存されたすべての変数はロールバックされなければならない、と下のテストケースに合格する必要があり、ロールバックする必要があります。

@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(ロールバックしない)に取り組んでいます。 (トランザクションマネージャとしてorg.springframework.orm.jpa.JpaTransactionManager使用)

Springコンテキスト:

<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に尋ねました。

UPDATE ::

テストケースに合格org.springframework.jdbc.datasource.DataSourceTransactionManager代わりにorg.springframework.orm.jpa.JpaTransactionManagerを使用することによって。しかし、今私はJPAエンティティを永続化できません。

+0

投票理由 – united

答えて

0

問題はMyBatisの(JDBC)と休止状態(JPA)との間の競合を解決することによって解決される:

プロパティは entityManagerFactory Beanに追加されるべき

jpaVendorAdapter

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

だからentityManagerFactory豆は次のようであるべきです。

詳細については、this questionの回答を参照してください。

関連する問題