Spring JpaTransactionManager не сохраняет объекты Activiti в БД

Ничего об Activiti не сохраняется в базе данных. Сущности приложения сохраняются в базе данных. Ниже по порядку расположены файл spring, файл persitence.xml и тестовый пример.

Используя профилировщик SQL Server, я вижу, что отдельная транзакция базы данных запускается для взаимодействия с базой данных, вызванного Activiti, и, кроме того, я вижу, что эта отдельная транзакция откатывается, а не фиксируется. Взаимодействие с другим приложением db происходит в другой транзакции, и эта конкретная транзакция фиксируется.

  1. Я думал, что с учетом моих конфигураций взаимодействие с базой данных Activiti будет происходить в той же транзакции, что и остальная часть приложения. Я много раз просматривал свои файлы конфигурации и код и не вижу в этом ничего плохого. Любые идеи, почему для взаимодействия Activiti db запускается отдельная транзакция?
  2. Конечно, предыдущий пункт является критическим вопросом. Однако было бы также интересно узнать, почему эта отдельная транзакция откатывается?

Весенний файл:

<context:annotation-config/>
<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="ActivitiTrialDataSource" class="org.apache.commons.dbcp.BasicDataSource" >
    <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
    <property name="url" value="jdbc:jtds:sqlserver://localhost:1433/ActivitiTrial" />
    <property name="username" value="ActivitiTrial" />
    <property name="password" value="ActivitiTrial" />
    <property name="defaultAutoCommit" value="false" />
    <property name="initialSize" value="5" />
</bean>


<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>


<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="ActivitiTrialDataSource" />
    <property name="persistenceUnitName" value="ActivitiTrial"/>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>



<!-- Activiti -->
<bean id="activitiDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
    <property name="targetDataSource" ref="ActivitiTrialDataSource" />
</bean>

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    <property name="databaseType" value="mssql" />
    <property name="dataSource" ref="activitiDataSource" />
    <property name="transactionsExternallyManaged" value="true" />
    <property name="transactionManager" ref="transactionManager" />
    <property name="databaseSchemaUpdate" value="false" />
    <property name="history" value="audit" />
    <property name="jobExecutorActivate" value="false" />
</bean>

<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    <property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>

<bean id="activitiRepositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="activitiRuntimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="activitiTaskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="activitiHistoryService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="activitiManagementService" factory-bean="processEngine" factory-method="getManagementService" />

файл persitence.xml:

<persistence-unit name="ActivitiTrial">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <properties>
        <property name="hibernate.archive.autodetection" value="hbm,class"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
        <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
        <property name="hibernate.hbm2ddl.auto" value="none"/>
        <property name="hibernate.show_sql" value="false"/>
        <property name="hibernate.ejb.metamodel.generation" value="disabled"/>
    </properties>
</persistence-unit>

Прецедент:

@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(defaultRollback=false)
@ContextConfiguration({"classpath:/springApplicationContext.xml"})
public class TrialTest {
    @Autowired
    RepositoryService activitiRepositoryService;

    @Autowired
    RuntimeService activitiRuntimeService;

    @Autowired
    TaskService activitiTaskService;


    @PersistenceContext(unitName="ActivitiTrial")
    EntityManager entityManager;



    @Test
    @Transactional
    public void trialTest() throws Exception {
        long entryMilliseconds = new Date().getTime();


        activitiRepositoryService.createDeployment().addClasspathResource("process-definitions/neville.bpmn20.xml").deploy();


        ApplicationEntity applicationEntity1 = new ApplicationEntity();
        applicationEntity1.name = "App entity 1";
        applicationEntity1.createDate = new Date();
        Session hibernateSessionBeforeActiviti = ((Session) entityManager.getDelegate());
        entityManager.persist(applicationEntity1);
        entityManager.flush();


        Map<String, Object> processVariables = new HashMap<String, Object>();
        processVariables.put("ApplicationEntityID", applicationEntity1.id);
        ProcessInstance processInstance = activitiRuntimeService.startProcessInstanceByKey("neville", processVariables);
        String processInstanceId = processInstance.getId();
        Task userTask = activitiTaskService.createTaskQuery().processInstanceId(processInstanceId).list().get(0);


        ApplicationEntity applicationEntity2 = new ApplicationEntity();
        applicationEntity2.name = "App entity 2";
        applicationEntity2.createDate = new Date();
        Session hibernateSessionAfterActiviti = ((Session) entityManager.getDelegate());
        entityManager.persist(applicationEntity2);
        entityManager.flush();


        System.out.println("Leaving trialTest() in : " + (new Date().getTime() - entryMilliseconds) + " milliseconds.");
    }
}

person neville.sequeira    schedule 11.09.2013    source источник


Ответы (2)


Я решил эту проблему, разрешив конфликт между MyBatis (JDBC) и Hibernate (JPA):

Вы должны добавить свойство jpaVendorAdapter к entityManagerFactory bean-компоненту:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="ActivitiTrialDataSource" />
    <property name="persistenceUnitName" value="ActivitiTrial"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
</bean>

Дополнительные сведения см. в ответе этот вопрос.

person Arya    schedule 25.06.2017

Я уже потратил много времени, пытаясь передать общий менеджер транзакций Spring и Activiti - и безрезультатно. Нет полного ответа на ваш вопрос, но я надеюсь, что это сэкономит вам время.

Форум Activiti:

Демо:

Эти репозитории показывают, что Activiti не принимает транзакции jpa/hibernate:

Вы также можете просмотреть демонстрацию https://github.com/Activiti/Activiti ( Activiti + Spring + Bitronix) может поможет (пока нет времени проверять).

P.S.

В качестве альтернативы обычной сделке я вижу компенсационные мероприятия.

person VB_    schedule 26.09.2013