2016-11-29 7 views
1

の作業コードをロールバックしません。不幸にもそれはうまくいかない。記録が残っているので、春のテストの@Rollbackは、以下のもの

//import everything 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = Test2.TestConfiguration.class) 
@Transactional 
public class Test2 { 

    @Autowired 
    private DataSource datasource; 

    @BeforeTransaction 
    public void createTable() throws SQLException { 
     datasource .getConnection() 
        .createStatement() 
        .execute("CREATE TABLE USERS (id bigint, size bigint, primary key (id))"); 
    } 

    @Rollback 
    @Test 
    public void test() throws SQLException { 
     datasource .getConnection() 
        .createStatement() 
        .execute("INSERT INTO USERS VALUES (5, 5)"); 
    } 

    @AfterTransaction 
    public void dropTable() throws SQLException { 
     ResultSet rs = datasource .getConnection() 
            .createStatement() 
            .executeQuery("SELECT * FROM USERS"); 
     boolean isEmpty = !rs.next(); 
     if (isEmpty) { 
      System.out.println("Rollback succeeded"); 
     } else { 
      System.out.println("Rollback failed"); 
     } 
     rs.close(); 

     datasource .getConnection() 
        .createStatement() 
        .execute("DROP TABLE USERS"); 
    } 

    @Configuration 
    public static class TestConfiguration { 

     @Bean 
     public DataSource driverManagerDataSource() { 
      DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); 
      String dbURI = "database/tests/DerbyDB/db"; 
      String connectionString = "jdbc:derby:" + dbURI; 
      if (!new File(dbURI).exists()) connectionString += ";create=true"; 
      driverManagerDataSource.setUrl(connectionString); 
      driverManagerDataSource.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver"); 
      return driverManagerDataSource; 
     } 

     @Bean 
     public PlatformTransactionManager platformTransactionManager() { 
      PlatformTransactionManager ptm = new DataSourceTransactionManager(driverManagerDataSource()); 
      return ptm; 
     } 
    } 
} 

春はそれが真実ではないデータベースを、ロールバック主張:

は、ここに私のテストクラスです。
どのように動作させるのですか?

gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext startTransaction 
INFO: Began transaction (1) for test context [[email protected] testClass = Test2, testInstance = [email protected], testMethod = te[email protected], testException = [null], mergedContextConfiguration = [[email protected] testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [o[email protected]3bf9ce3e]; rollback [true] 
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext endTransaction 
INFO: Rolled back transaction for test context [[email protected] testClass = Test2, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [[email protected] testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]. 
Rollback failed 
gru 01, 2016 12:26:14 PM org.springframework.context.support.GenericApplicationContext doClose 
INFO: Closing [email protected]45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy 

完全なログは以下の通りである。

gru 01, 2016 12:26:12 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames 
INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener] 
gru 01, 2016 12:26:12 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners 
INFO: Using TestExecutionListeners: [or[email protected]69d9c55, org.springframework.test[email protected]13a57a3b, org.springframewor[email protected]7ca48474, org.springfra[email protected]337d0578, org.springframew[email protected]59e84876, org.sp[email protected]61a485d2] 
gru 01, 2016 12:26:12 PM org.springframework.context.support.GenericApplicationContext prepareRefresh 
INFO: Refreshing [email protected]45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy 
gru 01, 2016 12:26:13 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init> 
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 
gru 01, 2016 12:26:13 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName 
INFO: Loaded JDBC driver: org.apache.derby.jdbc.EmbeddedDriver 
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext startTransaction 
INFO: Began transaction (1) for test context [[email protected] testClass = Test2, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [MergedContextConfig[email protected] testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [o[email protected]3bf9ce3e]; rollback [true] 
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext endTransaction 
INFO: Rolled back transaction for test context [[email protected] testClass = Test2, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [[email protected] testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]. 
Rollback failed 
gru 01, 2016 12:26:14 PM org.springframework.context.support.GenericApplicationContext doClose 
INFO: Closing [email protected]45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy 

答えて

2

私が理解、あなたはその初期化時にテーブルを作成し、あなたの試験方法で手動で新しい、独立したSpringコンテキストを作成しているから。

このコンテキストは独自のトランザクションマネージャとデータソースを使用するため、@Rollbackアノテーションの影響を受けません。つまり、テストクラス全体に対して定義された(暗黙の)スプリングコンテキストのコンテキストで処理されます。


はまた、いくつかのDBには、あなたが(ダービーけれどもわからない)CREATEコマンドをロールバックすることができないことに注意してください。


更新

もう一つの問題は、あなたがdatasource.getConnection()経由の接続を取得するとき、あなたが実際にトランザクションマネージャを使用していないということです。

DataSourceTransactionManagerからドキュメント:

アプリケーションコードではなく、標準のJava EEスタイルDataSource.getConnection()コールのDataSourceUtils.getConnection(DataSource)を経由してJDBC接続を取得するために必要とされます。 JdbcTemplateのようなSpringクラスは、この戦略を暗黙的に使用します。

+0

あなたは '@ContextConfiguration(classes = TestDerbyDatabaseInitializer.TestConfiguration.class)'でテストクラスに注釈をつけて、implictコンテキストを削除すると '@ Rollback'アノテーションが動作するのでしょうか? – Tyvrel

+1

1) '@ ContextConfiguration'アノテーションで作成されたSpringコンテキストを使う必要があります。混乱を避けるために他のコンテキストを作成しない、2)誤って管理されていない接続を使用しないようにプログラムでデータベースへの他の接続をプログラムで作成しない( 'DriverManager.getConnection()')、3)ロールバックすることができます(つまり'INSERT'ではなく' CREATE TABLE') - '@ BeforeTransaction'メソッドでデータベースを作成します。 –

+0

ありがとうございました。その答えは、Springのテストについてもっと理解してくれました。また、私はあなたのコメントに応じてコードを更新しましたが、私はまだそれを働かせることはできません。 – Tyvrel

0

私はこのラインcon.close();printTableName()メソッドがissuseを引き起こしたと思います。

接続を閉じるときにトランザクションがコミットされます。

トランザクションを処理するには、entitymanagerまたはspring data jpa repositoryを使用する方が良いです。

+0

Unfortunatelly、 'con.close();'を削除しても問題は解決しません。 – Tyvrel

+0

@Tyvrel明示的にロールバックしようとしましたか? 'con.rollback();' – Bryan

+0

もちろんです。どちらもうまくいきません。ポイントを逃してしまう - @ロールバックがどのように動作するのかを知る必要があり、単純なSQLスクリプトを実行するよりも簡単なエクササイズを理解できなかった。 – Tyvrel

関連する問題