Spring Transaction Integration not working

I’m using Camunda 7.3, Spring 4.2.4 and Hibernate 4.3.8 and I’m trying to use them with the same transaction as explained in Camunda Documentation. The transaction works ok with Hibernate operations but not with Camunda operations, if a transaction rollback occurs just the hibernate operations are reverted.

@Configuration
public class CamundaConfiguration {

  // Variables with connection Data

  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
    bean.setPersistenceUnitName("PostgreSQL");
    bean.setDataSource(dataSource());
    bean.getJpaPropertyMap().put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL82Dialect");
    bean.getJpaPropertyMap().put("hibernate.ejb.naming_strategy", NamingStrategyLowerCase.class.getCanonicalName());
    bean.getJpaPropertyMap().put("hibernate.jdbc.batch_size", 0);
    bean.getJpaPropertyMap().put("hibernate.cache.use_second_level_cache", true);
    bean.getJpaPropertyMap().put("hibernate.cache.use_query_cache", true);
    bean.getJpaPropertyMap().put("javax.persistence.sharedCache.mode", SharedCacheMode.ALL);
    bean.getJpaPropertyMap().put("hibernate.cache.default_cache_concurrency_strategy", "read-write");
    bean.getJpaPropertyMap().put("javax.persistence.validation.factory", validator);
    bean.getJpaPropertyMap().put("hibernate.cache.region.factory_class", SingletonEhCacheRegionFactory.class.getCanonicalName());
    bean.setPersistenceProviderClass(org.hibernate.jpa.HibernatePersistenceProvider.class);
    bean.setPackagesToScan("br.com.model");
    return bean;
    }

  @Bean
  public JpaTransactionManager transactionManager() {
    JpaTransactionManager bean = new JpaTransactionManager(entityManagerFactory());
    bean.getJpaPropertyMap().put("org.hibernate.flushMode", FlushMode.AUTO);
    bean.setDataSource(dataSource);
    bean.setPersistenceUnitName("PostgreSQL");
    return bean;
  }

  @Bean
  public DataSource dataSource() {
    HikariConfig config = new HikariConfig();
    config.setDriverClassName(driverClass);
    config.setJdbcUrl(jdbcUrl);
    config.setUsername(username);
    config.setPassword(password);
    config.setMaximumPoolSize(50);
    config.setConnectionTestQuery("select 1");

    HikariDataSource bean = new HikariDataSource(config);
    return new LazyConnectionDataSourceProxy(bean);
  }

  @Bean
  public ManagedProcessEngineFactoryBean processEngine() {
    ManagedProcessEngineFactoryBean processEngineFactoryBean = new ManagedProcessEngineFactoryBean();
    processEngineFactoryBean.setProcessEngineConfiguration(processEngineConfiguration());
    return processEngineFactoryBean;
  }

  @Bean
  public SpringProcessEngineConfiguration processEngineConfiguration() {
    SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();
    processEngineConfiguration.setDataSource(dataSource());
    processEngineConfiguration.setTransactionManager(transactionManager());
    processEngineConfiguration.setJobExecutorActivate(true);
    processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_TRUE);
    return processEngineConfiguration;
  }

  @Bean
  public TaskService taskService() throws Exception {
    return processEngine().getObject().getTaskService();
  }
}

The dataSource and transactionManager is the same used by Spring and Hibernate.

@Service
public class TaskManager {
  @Inject
  private TaskService taskService;

  @Transactional
  public void completeTask(String taskId, final Map<String, Object> variables) {
    org.camunda.bpm.engine.task.Task camundaTask = taskService.createTaskQuery().taskId(taskId).singleResult();
    taskService.complete(camundaTask.getId(), variables);

    // Hibernate Operations

    throw new RuntimeException("Exception test");
  }
}

When executed the code above a rollback will occur and the ‘Hibernate Operations’ are rollbacked but the operations executed in taskService.complete are not.

I already debugged the Camunda code and everything seems ok, I found a SpringTransactionInterceptor and the commands are executed inside a TransactionTemplate.execute() and at this point the transaction is active.

Hi Bruno,

Where do you run your code? Unit-Test or application server or servlet container?

Cheers,
Christian

Hi, I run this code in a servlet container.

I found out the answer and posted at http://stackoverflow.com/questions/37486116/camunda-spring-transaction-integration-not-working/40597562#40597562