2017-06-21 3 views
1

Ich möchte einen gemeinsamen Transaktionsmanager (JpaTransactionManager) für Ruhezustand und activiti verwenden, aber ich kann nicht! Und ich habe alle Internetquellen dafür gelesen! Hear ist ein einfaches Szenario (was auch nicht Hibernate verwenden !!):Verwalten Hibernate und Activiti mit Common TransactionManager

  1. speichern Variablen in Aufgabe
  2. speichern Variable in Aufgabe # Ausführung
  3. komplette Aufgabe

Szenario-Implementierung (in eine Feder-Bean-Methode mit @Transactional Anmerkung):

@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()); 
    } 
} 

Es ist offensichtlich: wenn 012.359.wirft Fehler, sollte die gesamte Transaktion rollbacked werden, so dass alle gespeicherten Variablen rollbacked werden sollte, und die folgenden Testfall übergeben werden sollen:

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

Aber es fehlschlägt, werden die Variablen an die DB verpflichtet (nicht rollbacked).

Frühling Kontext (mit org.springframework.orm.jpa.JpaTransactionManager als Transaktionsmanager):

<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> 

Versionen:

  • Activiti Version: 5.22.0
  • DB: h2 (auch mit Oracle in der Produktion getestet)

Was ist falsch an meinen Konfigurationen?

P.S.

  • Das Testprojekt wurde hochgeladen here. Diese Frage habe ich auch in alfresco forum gestellt.

UPDATE ::

Durch die Verwendung von org.springframework.jdbc.datasource.DataSourceTransactionManager statt org.springframework.orm.jpa.JpaTransactionManager den Testfall bestanden. Aber jetzt kann ich JPA-Entitäten nicht beibehalten.

+0

Down Abstimmung Grund? – united

Antwort

0

Das Problem wird durch Beilegung von Konflikten zwischen Mybatis gelöst (JDBC) und Hibernate (JPA):

jpaVendorAdapter Eigenschaft sollte auf entityManagerFactory Bohne hinzugefügt:

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

So entityManagerFactory Bohne so sein sollte:

<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> 

Für weitere Details siehe Antwort von this question.

Verwandte Themen