1

完了後にトランザクションをロールバックしないサービスの統合テストを作成しました。これは、dbを確認することと、テストを2回実行したときに発生するエラーからわかります。私はこの問題を午前中ずっとグーグルしていて、すべてが適切に設定されていると感じています。これはSQLServer2008に書き込むhibernate/jpaアプリです。他にどこを見ればよいかわかりません。以下のスニペット。

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class,
        TransactionalTestExecutionListener.class })
@TransactionConfiguration(defaultRollback=true)
@Transactional // extend transactional boundary to test class so that automatic rollback works properly
@ContextConfiguration(locations = {
        "file:./src/main/resources/AghostMobile.Service-business.service-context.xml",
        "file:./src/main/resources/AghostMobile.Service-service-context.xml",
        "file:./src/main/resources/AghostMobile.Service-dao-context.xml"})
public class ColorSchemeMigrationServiceIntTest {

    /**
     * The service being tested, injected by Spring
     *
     */
    @Autowired
    ColorSchemeMigrationService service;

    /**
     * The helper services, injected by Spring.
     *
     */
    @Autowired
    protected WebsitecolorpaletteuserdefinedService userPaletteService;
    @Test
    public void testSaveColorPalette() {
        Integer mobileWebsiteId = Integer.valueOf(386);
        Integer custId = Integer.valueOf(15);
        Integer siteId = Integer.valueOf(2);
        String user = "Test";

        Websitecolorpaletteuserdefined palette = service.translateColorScheme(mobileWebsiteId, custId, siteId, user);

        service.saveColorPalette(palette);

        Websitecolorpaletteuserdefined response = userPaletteService.findWebsitecolorpaletteuserdefinedByCustIdAndSiteId(custId, siteId);

        assertNotNull("User palette not found.", response);
        assertEquals("CustId is not the expected value.", custId, response.getCustId());
        assertEquals("SiteId is not the expected value.", siteId, response.getSiteId());
    }

現在、次のBeanを定義しています。

<!-- ******************************************************************** -->
<!-- Setup the transaction manager -->
<!-- ******************************************************************** -->
    <!-- Using Atomikos Transaction Manager -->
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init"
        destroy-method="close">
        <property name="forceShutdown" value="true" />
        <property name="startupTransactionService" value="true" />
        <property name="transactionTimeout" value="60" />
    </bean>

    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" />
    <!-- Configure the Spring framework to use JTA transactions from Atomikos -->
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="atomikosTransactionManager" />
        <property name="userTransaction" ref="atomikosUserTransaction" />
        <property name="transactionSynchronizationName" value="SYNCHRONIZATION_ON_ACTUAL_TRANSACTION" />
    </bean>
<!-- ******************************************************************** -->
<!-- Setup a data source -->
<!-- ******************************************************************** -->
<!-- Using Apache DBCP Data Sources -->
<bean name="hostDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
    <property name="driverClassName" value="${My_JDTs_to_AgHost_Host_scheme.connection.driver_class}" />
    <property name="username" value="${My_JDTs_to_AgHost_Host_scheme.connection.username}" />
    <property name="password" value="${My_JDTs_to_AgHost_Host_scheme.connection.password}" />
    <property name="url" value="${My_JDTs_to_AgHost_Host_scheme.connection.url}" />
    <property name="maxIdle" value="${My_JDTs_to_AgHost_Host_scheme.minPoolSize}" />
    <property name="maxActive" value="${My_JDTs_to_AgHost_Host_scheme.maxPoolSize}" />
</bean>

<!-- ******************************************************************** -->
<!-- Setup each persistence unit -->
<!-- ******************************************************************** -->
            <!-- Configure a JPA vendor adapter -->
            <bean id="My_JDTs_to_AgHost_Host_schemeJPAVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="${My_JDTs_to_AgHost_Host_scheme.show_sql}" />
                <property name="generateDdl" value="${My_JDTs_to_AgHost_Host_scheme.generateDdl}" />
                <property name="databasePlatform" value="${My_JDTs_to_AgHost_Host_scheme.dialect}" />
            </bean>
            <!-- EntityManager Factory that brings together the persistence unit, datasource, and JPA Vendor -->
            <bean id="My_JDTs_to_AgHost_Host_scheme" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                <property name="dataSource" ref="hostDataSource" />
                <property name="persistenceUnitName" value="My_JDTs_to_AgHost_Host_scheme" />
                <property name="jpaVendorAdapter" ref="My_JDTs_to_AgHost_Host_schemeJPAVendorAdapter" />
                    <property name="jpaPropertyMap">
                        <map>
                                    <entry key="hibernate.transaction.manager_lookup_class" value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup" />
                                    <!-- <entry key="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" /> -->
                                    <entry key="hibernate.connection.release_mode" value="on_close" />
                        </map>
                    </property>
            </bean>

これにより、データを更新できますが、トランザクションをロールバックすることはできません。そのため、トランザクションマネージャーorg.springframework.jdbc.datasource.DataSourceTransactionManagerを使用しています。「Setuptransactionmanager」ブロックの3つのBeanを次のように置き換えました。

    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="hostDataSource" />
    </bean>

これにより、IllegalStateExceptionで失敗するテストが残りました。このメソッドには呼び出し元のスレッドのトランザクションが必要であり、存在しません。例外も述べています:

Possible causes: either you didn't start a transaction,
it rolledback due to timeout, or it was committed already.
ACTIONS: You can try one of the following: 
1. Make sure you started a transaction for the thread.
2. Make sure you didn't terminate it yet.
3. Increase the transaction timeout to avoid automatic rollback of long transactions;
   check [http://www.atomikos.com/Documentation/JtaProperties][1] for how to do this.

私はそのドキュメントをまだ読んでいないことを認め、これらの更新を投稿した後に読みます。私はまた、有望に見えたこのスレッドを見つけました:persistence-unit、異なるhibernate.transaction.manager_lookup_classプロパティ。BeanMy_JDTs_to_AgHost_Host_schemeでコメントアウトされていることがわかります。これはかなり惨めに失敗しました。しかし、おそらく私はそれを適切に使用しませんでした。

私もこのスレッドを見つけました:Spring / JTA / JPA DAO統合テストはロールバックしませんか?。これは非常に有望に見えますが、それが私に言っていることをどのように使用するかはわかりません。

4

2 に答える 2

1

答えはここで見つかりました:Spring / JTA / JPA DAO統合テストはロールバックしませんか?。データソースを以下に変更しました。

<bean name="hostDataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" destroy-method="close" >
    <property name="driverClassName" value="${My_JDTs_to_AgHost_Host_scheme.connection.driver_class}" />
    <property name="user" value="${My_JDTs_to_AgHost_Host_scheme.connection.username}" />
    <property name="password" value="${My_JDTs_to_AgHost_Host_scheme.connection.password}" />
    <property name="url" value="${My_JDTs_to_AgHost_Host_scheme.connection.url}" />

    <property name="maxPoolSize" value="20" />
    <property name="reapTimeout" value="300" />
    <property name="uniqueResourceName" value="myappDatabase" />
</bean>
于 2012-10-19T18:46:14.280 に答える
0

ロードされたコンテキストにBeanがありDataSourceTransactionManagerますか?

DataSourceTransactionManagerの例

セクション9.3を参照してください

于 2012-10-03T18:11:22.097 に答える