【问题标题】:Java spring Junit Transaction won't rollback databaseJava spring Junit Transaction不会回滚数据库
【发布时间】:2017-03-27 09:39:27
【问题描述】:

我想在每次测试后回滚数据库,但它不起作用,我尝试了不同类型的事务管理配置。 createNewItem method 对象仍在其他测试中显示。

回滚的目标是让每个测试都拥有完全相同的数据库对象和预期的新 ID

上下文配置:

 @Configuration
 @EnableJpaRepositories("se.system.repository")
 @EnableTransactionManagement
 public class ContextConfiguration{

@Bean(name = "hsqldb")
public DataSource InMemoryDataSource() {
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    EmbeddedDatabase database = builder.setType(EmbeddedDatabaseType.HSQL)
            .addScript("classpath:se/system/sql/create-db.sql")
            .addScript("classpath:se/system/sql/insert-data.sql").build();

    return database;
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory factory) {
    return new JpaTransactionManager(factory);
}


@Bean
public JpaVendorAdapter jpaVendorAdapter() {

    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
    adapter.setDatabase(Database.HSQL);
    adapter.setShowSql(false);
    adapter.setGenerateDdl(false);
    return adapter;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setDataSource(InMemoryDataSource());
    factory.setJpaVendorAdapter(jpaVendorAdapter());
    factory.setPackagesToScan("se.system.model");
    return factory;
}

使用 hsqldb 进行 Junit 测试:

 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes = {ContextConfiguration.class })
 @TestExecutionListeners
 @Transactional
 public class ServiceTest {

@Rule
public ExpectedException thrown = ExpectedException.none();

private static Service service;

private static AnnotationConfigApplicationContext context;

@BeforeClass
public static void setup() {
    context = new AnnotationConfigApplicationContext();
    context.register(ContextConfiguration.class);
    context.scan("se.system");
    context.refresh();
    Service = context.getBean(Service.class);
}


@Test
public void createNewItem() {

    System.out.println(((List<Item>) service.getAllitem()).size());
    Item item = Service
            .saveOrUpdateItem(new Item("Title", "Description"));
    System.out.println(Item);
    assertEquals(new Long(4L), Item.getId());
}

【问题讨论】:

  • 嗨,您在哪里将 autocommit 设置为 false?
  • 嘿,我也在找那个,但是我没有找到把它变成假的地方,所以我认为它默认已经是假的了。
  • 能否贴出带有saveOrUpdateItem方法的服务类代码?
  • 即使测试确实回滚,即取消插入 Item 对象,如果它是由标识列生成的,id 生成器也不会回滚。所以在同一个数据库上运行两次测试如果第一次成功,第二次肯定会失败。
  • 好的,但如果我将它们全部打印出来,测试后数据库对象仍然存在

标签: java spring junit transactions hsqldb


【解决方案1】:

这就是我通常注释我的测试类的方式:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { JPAUnitTestConfiguration.class })
@Transactional //rollback if exception occurs during test method
@TransactionConfiguration(defaultRollback = true) //rollback at end of method
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class FooBarTest {
}

将@TransactionConfiguration(defaultRollback = true) 添加到您的测试类。

我的交易配置:

import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import ch.ams.pois.repository.AuthTokenRepository;
import ch.ams.pois.repository.GroupRepository;
import ch.ams.pois.repository.InvitationRepository;
import ch.ams.pois.repository.LocationRepository;
import ch.ams.pois.repository.UserRepository;


@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = JPAConfiguration.JPA_REPOSITORIES_BASE_PACKAGES, 
includeFilters = @ComponentScan.Filter(value = { 
        UserRepository.class, LocationRepository.class, 
        GroupRepository.class, AuthTokenRepository.class, 
        InvitationRepository.class }, 
        type = FilterType.ASSIGNABLE_TYPE))
public class JPAUnitTestConfiguration extends JPAConfiguration {

    @Bean
    public DataSource dataSource() throws SQLException {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.H2).build();
    }
}

持久层的依赖:

<dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.3.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.3.173</version>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.2-1003-jdbc4</version>
        </dependency>

【讨论】:

  • 它仍然不会回滚,并且不推荐使用 TransactionConfiguration
  • 目前这对您有用吗?如果可以,您能否分享一下您是如何配置事务管理的?
  • 它对我有用。刚刚测试过了。但我使用较旧的库,因为该项目不再更新。
猜你喜欢
  • 1970-01-01
  • 2018-09-15
  • 2017-07-22
  • 1970-01-01
  • 2016-05-03
  • 2019-07-27
  • 2023-01-12
  • 2013-05-08
  • 1970-01-01
相关资源
最近更新 更多