Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 如果@Transactional_Spring_Spring Boot_Spring Data_Spring Boot Test_Spring Data Jdbc - Fatal编程技术网

Spring 如果@Transactional

Spring 如果@Transactional,spring,spring-boot,spring-data,spring-boot-test,spring-data-jdbc,Spring,Spring Boot,Spring Data,Spring Boot Test,Spring Data Jdbc,我有一个简单的Spring引导应用程序,它使用Spring数据JDBC存储库并公开RESTAPI。除了我的集成测试之外,一切都正常运行。请参阅下面的存储库配置摘录 @Configuration @EnableJdbcRepositories class RepositoryConfig : AbstractJdbcConfiguration() { @Bean @Profile("int-test") fun intTestDataSource():

我有一个简单的Spring引导应用程序,它使用Spring数据JDBC存储库并公开RESTAPI。除了我的集成测试之外,一切都正常运行。请参阅下面的存储库配置摘录

@Configuration
@EnableJdbcRepositories
class RepositoryConfig : AbstractJdbcConfiguration() {

    @Bean
    @Profile("int-test")
    fun intTestDataSource(): DataSource {
        return EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("sql/h2/schema_create.sql")
                .build()
    }

    @Bean
    fun namedParameterJdbcOperations(dataSource: DataSource): NamedParameterJdbcOperations {
        return NamedParameterJdbcTemplate(dataSource)
    }

    @Bean
    fun transactionManager(dataSource: DataSource): TransactionManager {
        return DataSourceTransactionManager(dataSource)
    }
}
集成测试如下

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("int-test")
@Transactional
class OrganizationControllerIntTest {

    @Autowired
    private lateinit var organizationRepository: OrganizationRepository

    @Autowired
    private lateinit var restTemplate: TestRestTemplate

    @Autowired
    private lateinit var testDataGenerator: TestDataGenerator

    @BeforeEach
    fun beforeEach() {
        val organizations = testDataGenerator.organizations(10).toList()
        organizationRepository.saveAll(organizations)
    }

    @Test
    fun `When GET organizations then return all organizations`() {
        val result = restTemplate.getForEntity("/organizations", String::class.java)
        assertThat(result?.statusCode, equalTo(HttpStatus.OK))
        assertThat(result?.body, containsString("items"))
    }
}

如果未应用
@Transactional
注释,则测试成功。因为我需要在每次测试后回滚更改,所以我希望使测试具有事务性。问题是,在这种情况下,响应不包含任何项,例如数据库将为空,我无法找出原因。

使用带有系统测试的
@Transactional
将无法工作

发生的情况是在每个方法插入数据库之前,
@中的数据但是事务从未提交。数据仅在同一事务中可见

现在,您向服务器发送一个HTTP请求,服务器将打开到数据库的新连接并启动一个新事务。但是,由于来自另一个事务的数据没有提交,因此它不会看到任何内容

@Transactionl
仅在使用
MockMvc
时有效,因为它将在同一事务和线程中运行。实际发出HTTP请求时,情况并非如此

为每个测试使用数据设置,但在进行完整系统测试时应谨慎!你可以:

  • 如果您真的想要进行系统测试,那么以一种无所谓的方式编写测试
  • 使用
    MockMvc
    运行测试,而不是实际的HTTP请求,这将使它(重新)使用相同的事务
  • 不要编写系统测试,而是使用
    @WebMvcTest
    测试控制器

  • 如果您的测试是事务性的,那么在测试之后不会提交和回滚任何内容。但是,它仅在事务内部可见。当您调用一个实际端点时,该端点没有看到数据,只是因为它尚未提交。使用
    @Transactional
    进行完整的集成测试是行不通的(在使用<代码> MoCKMVC < /COD>时,它会起作用,因为它不会发出实际请求并在同一线程和事务中运行。这是有意义的。那么,在每次集成测试之后/在每次集成测试之前重新设置数据库状态通常是什么?只是在<代码> >中删除所有的< < /代码>方法)。您是否考虑转换COM?你能把答案写下来,这样我就可以接受它,并把它提供给别人吗?