1

我已经看到了很多问题,但他们的所有解决方案仍然不清楚。这是我设置的 Spring Context 文件

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    ..
    ...


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

    ...
    ...

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

    <bean id="entityManagerFactory1"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        autowire="byName">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="packagesToScan" value="com.my.dom.domain" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.Oracle10gDialect
                </prop>             
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.jdbc.fetch_size">50</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
        <property name="persistenceUnitName" value="PersistenceUnit1"></property>
    </bean>

    <bean id="EntityManagerFactory2"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        autowire="byName">
        <property name="dataSource" ref="myDataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="packagesToScan" value="com.my.dom.domain" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.H2Dialect
                </prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.jdbc.fetch_size">50</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
     ..
     ...     


    <bean id="entityManager1" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory1" />
    </bean>
    <tx:annotation-driven transaction-manager="entityManager1" />

    <bean id="EntityManager2" factory-bean="EntityManagerFactory2" factory-method="createEntityManager" autowire="byName" scope="prototype"/>
    <tx:annotation-driven transaction-manager="EntityManager2" />


    <context:component-scan base-package="com.my.dom" />

    <jpa:repositories base-package="com.my.dom.repository"
        entity-manager-factory-ref="entityManagerFactory"
        transaction-manager-ref="transactionManager" />

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>


</beans>

所有数据源和其他连接 bean 都已就位并且工作正常。

我的DAO代码如下包com.my.dom.dao;

@Component
public class MyDAOImpl implements MyDAO {

@PersistenceContext(unitName="PersistenceUnit1")
EntityManager entityManager; // this is IAR EntityManager.

@Override
@Transactional
public boolean saveMyGroups(
        List<MyGroups> theGroups) {

    logger.info("Entering method -  saveFuturetheGroups ");
    //entityManager.getTransaction().begin();
    for(MyGroups pg : theGroups){
        MyGroups attachedENtity = entityManager.merge(pg);
        entityManager.persist(pg);
    }
    //entityManager.getTransaction().commit();
    entityManager.flush();
    logger.info("Exiting method -  saveFuturetheGroups ");
    //List<MyGroups> savedEntities = futureProcGrpRepository.save(theGroups);
    return true;
}

}

我在类路径中有所有 cglib 和 aopalliance1.0.jar,正如Spring+JPA @Transactional 中所建议的那样,没有提交

我的代码仍然没有将更改提交到数据库。任何帮助指针都会非常有帮助。

该代码显示了 select 和 insert sql 语句,没有抛出异常,但代码没有提交。@Transactional 注释有什么问题吗?

在这里定义多个实体管理器有什么问题吗?


好的,我发现如果我使用 @Transactional(propagation=Propagation.REQUIRES_NEW)

在我的方法之上,它提交了更改!但根据我的理解,Propagation 的默认值是“REQUIRED”,任何方式都会开始一个新的交易并应该在最后提交?任何指针我现在真的很困惑!

谢谢香港

请注意,我是从 A Junit 测试用例运行的,它是否有可能明确回滚更改?我在日志中看到类似以下内容

INFO : org.springframework.test.context.transaction.TransactionalTestExecutionListener - Rolled back transaction after test execution for test context [[TestContext@a5503a testClass = ProcessingGroupsTestCase, testInstance = null(com.wellmanage.dos.processingGroups.ProcessingGroupsTestCase), testMethod = testSave@ProcessingGroupsTestCase, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1363f5a testClass = ProcessingGroupsTestCase, locations = '{classpath:applicationContext.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]]

谢谢香港

4

4 回答 4

4

好了朋友们!!这都是我的愚蠢……我相信我应该承认这一点。我一直在通过我的 TestCase 运行整个 DAO 和服务,而我只是在我的 TestCase 中忽略了以下内容。

@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
@Transactional

defaultRollback=true 是罪魁祸首。

我学到了什么教训。永远不要忽视任何代码,总是试图从代码的开头找到问题。

因此,要使 Spring 与 JPA 一起工作 - 具有正确的上下文条目(如我的示例中所示) - 使用 @Transactional 就像在我的 DAO 中一样。

你应该准备好了。

谢谢香港

于 2013-06-14T04:29:02.973 回答
3

默认情况下,对于 junit 测试,defaultRollback 设置为 true,这意味着,即使您不指定 @TransactionConfiguration,通过 junit 测试更新的数据也会被回滚。

显式设置 defaultRollback=false 将解决此问题。

@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)

于 2013-07-24T19:25:04.297 回答
0

你要在你的代码上指定你的事务管理器

@Transactional("entityManager1")
public boolean saveMyGroups(
于 2013-06-13T12:03:41.630 回答
0

就我而言,您只是不想将 @Transactional 注释放在测试本身(或它所在的类)上,它会解决问题而不必包括:

@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)

这可能会使单元测试变得困难,并且默认情况下是“真实的”,这是有充分理由的。

所以只需让你的控制器层方法@Transactional 并且不要在测试中这样做 - 他们会看到修改后的数据。

于 2014-02-02T21:13:08.190 回答