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.