2010-10-29 12 views
12

Spring-testini başarılı bir şekilde kullanmadan JDBC işlem geri almayı deniyorum. Aşağıdakileri çalıştırdığımda SQL güncelleştirmesi her zaman işlenir.İlkbaharda geri alma işlemleri JDBC testleri

Yanlış yapıyorum
package my.dao.impl; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.annotation.Rollback; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.TestExecutionListeners; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; 
import org.springframework.test.context.transaction.TransactionConfiguration; 

import javax.sql.DataSource; 
import java.sql.Connection; 
import java.sql.Statement; 

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class}) 
@ContextConfiguration(locations={"classpath:ApplicationContext-test-DAOs.xml"}) 
@TransactionConfiguration(defaultRollback = true) 
public class ConfirmationMatchingDAOImplTest { 

    @Autowired 
    private DataSource dataSource; 

    @Test 
    public void shouldInsertSomething() throws Exception { 
     final Connection connection = dataSource.getConnection(); 
     final Statement statement = connection.createStatement(); 
     statement.executeUpdate("insert into TEST_INSERT values (1, 'hello')"); 
     statement.close(); 
     connection.close(); 
    } 
} 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> 
    <property name="url" value="jdbc:sqlserver://makeitfunky:1490;databaseName=fonzie"/> 
    <property name="username" value="ralph"/> 
    <property name="password" value="p0n1es_R_kew1"/> 
</bean> 

?

Ayrıca, çok fazla ek not kullanıyor muyum? Biraz daha temiz yapabilir miyim?

cevap

16

, Bahar varsayılan DependencyInjectionTestExecutionListener, DirtiesContextTestExecutionListener ve TransactionalTestExecutionListener tarafından yapılandırır. TransactionalTestExecutionListener, varsayılan geri alma semantikleri ile işlem testi yürütme sağlar. Test sınıfınızda @TestExecutionListeners bildirgesini açıkça bildirerek ve TransactionalTestExecutionListener öğelerini dinlemeden, işlem desteğini devre dışı bırakıyorsunuz.

Ayrıca @Transactional ek notunu sınıf veya yöntem düzeyinde de eklemelisiniz.

DataSourceTransactionManager tarafından yönetilen bir işlemsel Bağlantı almak için DataSourceUtils'u da kullanmalısınız.

+0

@TestExecutionListeners kaldırdım ve @ Transactional ekledi. Daha sonra uygulama bağlamına (DataSourceTransactionManager) bir transactionManager fasulye eklemeliydim. Txn geri alınmadı, bu yüzden @TransactionConfiguration (defaultTalkback = true) ekledim. Txn hala geri alınmadı, bu yüzden test yöntemine @Rollback ekledim. Ancak o zaman bahar günlüğünün txn'yi geri aldığını gördüm, ancak güncelleme hala DB'ye devam ediyor. SQL Server ve onun sürücüsü ile belki bir şey? – Synesso

+1

Cevabım için DataSourceUtils eklendi. –

+0

Ah, son yorumunuzdan haberdar edilmedim. Bu arada, veri kaynağını TransactionAwareDataSourceProxy'de sarmak için bağlamımı değiştirdim. İşe yaradı. İşte orada, aynı şeyi yapmanın iki yolu var. Şimdi bu 7 ek açıklamadan hangilerinin kurtulabildiğini ve hala işe yaradığını görebiliyorum. – Synesso

1

Test yöntemi için @Transactional'un olmaması olabilir mi? Açıkça @TestExecutionListeners ek açıklama kullanarak test yürütme dinleyicileri yapılandırmazsanız

+1

Ben @Transactional eklendi ve hiçbir etkisi yoktu. Ayrıca @Rollback ekledim ve hala bir etkisi olmadı. – Synesso

0

Baharda @Transactional ek açıklama kullanırken, sizin Bahar yapılandırma dosyasına aşağıdaki satırı eklemeniz gerekir: transactionManager mülkiyet tanımlanan işlem yöneticisi fasulye bir başvuru tutan

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

Yaylı yapılandırma dosyası. Bu kod, Spring'e işlem durdurucusunu uygularken @Transaction açıklamasını kullanmasını söyler. Bu olmadan, @ Transactional notu göz ardı edilir ve kodunuzda hiçbir işlem kullanılmaz.

Source on IBM website

+1

Aslında sorunun ne olduğunu hatırlayamıyorum, ama ekstra bilgi için teşekkürler. – Synesso

0

ek bilgiler: Bu hat

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

transaction-manager özelliğinin varsayılan değer "TransactionManager" dir için

. Bu özellik yalnızca transactionManager'ın bean kimliği/adı 'transactionManager' değilse gereklidir. Sen sınıf düzeyinde @Transactional eklemem gerekiyor

<tx:annotation-driven /> 
0

: Yani sadece belirlemek zorunda. Böyle şey: Burada txManager

@TransactionConfiguration(transactionManager = "txManager",defaultRollback = true) 
@Transactional 

application context dan İşlem yöneticisi bir örneği veya fasulye kimliğidir.Eğer yaklaşık sürümü 3,1

@Transactional 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {TestDbConfig.class, SomeService.class}) 
public class SomeTest { 

@Inject 
private SomeService someService; 

@PersistenceContext 
private EntityManager em; 

@Test 
public void someTest() {} 

beri bu güzel çalışır olmayan xml yöntemini kullanıyorsanız

<!-- Transaction Manager --> 
    <bean id="txManager" 
      class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

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

Test yapılandırma sonra bu halini alır. @EnableTransactionManagement bildirimi ve genel bir test defaultRollback bildirme gerçeği. Bu büyük projeler için özellikle yararlı olur.

@Configuration 
@PropertySource(value = "classpath:app.properties") 
@EnableTransactionManagement 
@TransactionConfiguration(defaultRollback = true) 
public class TestDbConfig { 

//read the parameters from properties 
@Value("${hibernate.dialect:unset}") 
private String hibernateDialect; 

@Bean 
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { 
    return new PropertySourcesPlaceholderConfigurer(); 
} 

@Bean 
public PlatformTransactionManager transactionManager() { 
    //for example 
    JpaTransactionManager transactionManager = new JpaTransactionManager(); 
    transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject()); 
    return transactionManager; 
} 

@Bean 
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { 
    //set the datasource 
    //set the JpaVendorAdapter 
    //set the packagesToScan 
    return some sort of LocalContainerEntityManagerFactoryBean; 
} 

@Bean 
DataSource dataSource() { 
    return dataSource from jndi or a DriverManagerDataSource(); 
} 

}

2

bu ek açıklama eklemek ve hiçbir rulo geri Test durumlarda olacaktır:

My açıklama şöyle
@TransactionConfiguration(defaultRollback=false) 

:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "/../applicationContext.xml" }) 
@TransactionConfiguration(defaultRollback=true) 
public class DBCreatorTest {