Spring JpaTransactionManager不将Activiti实体保存到DB

时间:2013-09-11 19:00:33

标签: spring hibernate jpa activiti transactionmanager

没有关于Activiti的内容被保存到数据库中。应用程序实体正在保存到数据库中。下面依次是spring文件,persitence.xml文件和测试用例。

使用SQL Server探查器,我看到为Activiti引起的数据库交互启动了一个单独的数据库事务,而且我看到单独的事务正在回滚而不是被提交。其他应用程序数据库交互正在另一个事务上发生,并且正在提交此特定事务。

  1. 我认为,根据我的配置,Activiti数据库交互将发生在与应用程序其余部分相同的事务中。我已经多次浏览了我的配置文件和代码,并且没有看到任何错误。任何想法为什么为Activiti数据库交互启动单独的事务?
  2. 当然前一项是关键问题。但是,了解为什么要回滚单独的事务也很有趣?
  3. Spring文件:

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

2 个答案:

答案 0 :(得分:0)

我已经浪费了大量时间尝试将常见的事务管理器传递给Spring和Activiti - 并且没有结果。没有完全回答你的问题,但我希望它能为你节省一些时间

Activiti论坛:

演示:

这些回购说明Activiti不接受jpa / hibernate事务:

您还可以看到演示https://github.com/Activiti/Activiti (Activiti + Spring + Bitronix)它可能会有所帮助(我还没有时间检查它)。

P.S。

作为普通交易的替代方案,我看到了补偿事件。

答案 1 :(得分:0)

我通过解决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>

有关详细信息,请参阅this question的回答。