2016-03-30 18 views
0

Ich erwarte, dass die Daten in die Datenbank geschrieben werden, nachdem die Methode mit @Transactional abgeschlossen ist. Ist dies eine gültige Annahme für meinen JUnit-Test bei Verwendung einer HSQL-Datenbank? Ich verwende HSQL db für die Entwicklung und Oracle für meine bereitgestellte Anwendung. Web App, implementiert in WebSphere, entwickelt in RSA. Im Folgenden finden Sie eine Zusammenfassung meiner Konfiguration, einschließlich POM und JUnit-Test:Die Transaktionsverwaltung scheint bei Spring Tests nicht zu funktionieren

POM: 
3.2.9.RELEASE 
<groupId>org.mybatis</groupId> 
<artifactId>mybatis</artifactId> 
<version>3.2.3</version> 

<groupId>org.mybatis</groupId> 
<artifactId>mybatis-spring</artifactId> 
<version>1.2.1</version> 

APPLICATION CONTEXT: 
<!-- the bean for transaction manager for scoping/controlling the transactions --> 
<bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dbDataSource" /> 
</bean> 
<tx:annotation-driven transaction-manager="transactionManager" /> 

<jee:jndi-lookup id="dbDataSource" jndi-name="jndi/HSQLDatasource" expected-type="javax.sql.DataSource" /> 

<!--Mapper--> 
<bean id="campaignMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> 
    <property name="mapperInterface" 
     value="com.abc.persistence.mapper.CampaignMapper" /> 
    <property name="sqlSessionTemplate"> 
     <bean class="org.mybatis.spring.SqlSessionTemplate"> 
      <constructor-arg index="0" ref="sqlSessionFactoryForBatch" /> 
      <constructor-arg index="1" value="BATCH" /> 
     </bean> 
    </property>  
</bean> 

<!-- SqlSessionFactory For Batch --> 
<bean id="sqlSessionFactoryForBatch" class="org.mybatis.spring.SqlSessionFactoryBean"> 
    <property name="dataSource" ref="dbDataSource" /> 
    <property name="typeAliasesPackage" value="com.abc" /> 
    <property name="mapperLocations" value="classpath*:com/mybatis/mappers/**/*.xml" /> 
</bean> 

JUNIT: 
//junit class extends a base class that initializes HSQL db 
//jdbcConnection.setAutoCommit(false); 

    @Autowired 
    CampaignMapper campaignMapper; 

    @Transactional 
    @Test 
    public void testInsert(){ 

     for(Campaign record:campaignsFromFile){ 
      record.setRowLastUpdateId(rowLastUpdateId); 
      record.setCampaignId(campaignId); 
      campaignMapper.insertCampaignRecord(record); 
     } 
     //At this point I expect that the data would NOT be written to the database 
     //other method code 

     }//end of method 
     //At this point I expect that the data would be written to the database 

Antwort

2

standardmäßig Frühling wird die Transaktion im Test Kontexten Rollback. Ist dies nicht das Verhalten Sie erwarten, können Sie immer @Rollback Annotation mit false Wert verwenden:

@Transactional 
@Test 
@Rollback(false) 
public void testInsert() { ... } 

Wird durch Zufall sind Sie Frühlings-4.2.x-Release verwenden, können Sie die neue @Commit Anmerkung verwenden, die a neue Anmerkung, die als direkter Ersatz für @Rollback(false) verwendet werden kann. Sie können mehr über Transaction Management in Spring Test Contexthere lesen.

+0

Meine Erwartung ist, dass die Datensätze nicht in die Datenbank geschrieben werden sollen, bis die Methode beendet wird. Wenn ich jedoch in debug ausführen, einen Haltepunkt nach dem Einfügen setzen und die Datenbank nach jedem Einfügen (in der Schleife) abfragen, sehe ich die einzelnen Datensätze einzeln in die Datenbank geschrieben. Ich erwarte, dass sie erst nach Abschluss der Methode geschrieben werden. Vielen Dank für den Einblick auf @Rollback, da es nützlich sein wird, nachdem ich das andere Problem zum ersten Mal korrigiert habe. – jimmy

+0

Entfernen Sie dann die 'Transaktional' und' Rollback' und verwalten Sie die Transaktion manuell mit der 'TestTransaction' Abstraktion. Sie können die Methoden 'start',' end' und 'flagForCommit' verwenden. –

+0

Sorry, aber jetzt bin ich verwirrt. Wenn ich diesen Kommentar richtig gelesen habe, kann ich meinen Code nicht so testen, wie ich ihn verwenden möchte. Ich kann Transactional nicht verwenden. Ich muss es durch TestTranaction ersetzen. Ich erwartete, dass dies eine direkte Ersetzung Annotation für Transactional für den Einsatz in Junit-Tests ist, aber das scheint nicht der Fall zu sein. Ich habe bei TestTranaction nach Hilfe gesucht, aber nichts nützliches bekommen. Wenn es etwas völlig anderes ist, dann weiß ich nicht, wie ich Vertrauen in meinen Code haben kann, wenn ich ihn deploye, wenn ich sein Verhalten in meiner Entwicklungsumgebung nicht überprüfen kann. – jimmy