删除未完成之前的插入操作
删除未完成之前的插入操作
你好,我正在使用Spring Boot Hibernate在MySQL中测试一种记录删除-插入-删除的操作,我注意到一个问题,即在插入发生时,似乎记录没有完全被删除。
在Hibernate启动时创建了3条初始记录(通过类路径中的data.sql文件):
insert into car(id, name, color) values (1, 'Toyota Camry', 'blue');
insert into car(id, name, color) values (2, 'Suzuki Swift', 'yellow');
insert into car(id, name, color) values (3, 'Nissan Qashqai', 'red');
操作如下:
(1)创建初始记录
(2)删除所有记录
(3)添加一条新记录
(4)再次删除所有记录
在执行断言时,发现结果列表仍然包含最后一条记录,因此断言失败。
我想知道这是否是删除操作在插入发生之前没有完成造成的。
如果您能提供一些见解,非常感谢您。谢谢。
模型(Car.java):
package com.example.demo.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @ApiModel(value = "Car", description = "The model for car") @Schema @Entity @Data public class Car { @ApiModelProperty(notes = "Car ID.", example = "12345", required = false, position = 0) @Id @GeneratedValue private Long id; @ApiModelProperty(notes = "Car name.", example = "Suzuki Swift 2020", required = true, position = 1) @NotNull @Size(min = 1, max = 30, message = "Name must have length between 1 and 30") private String name; @ApiModelProperty(notes = "Car color.", example = "blue", required = true, position = 2) @NotNull @Size(min = 1, max = 30, message = "Color must have length between 1 and 30") private String color; }
仓库(CarRepository.java):
package com.example.demo.repo; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.example.demo.model.Car; @Repository public interface CarRepository extends JpaRepository{ }
服务(TestService.java):
package com.example.demo.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.example.demo.model.Car; import com.example.demo.repo.CarRepository; @Service public class TestService { @Autowired private CarRepository carRepository; public ListgetAllCars() { return carRepository.findAll(); } @Transactional public void addNewCar(Car car) { carRepository.save(car); } @Transactional public void deleteAllCars() { carRepository.deleteAll(); } }
JUnit测试:
... ...... @Test public void shouldBeAbleToDeleteCarAndAddCarAndGetAllCars() { testService.deleteAllCars(); Car car = new Car(); car.setName("123456789012345678901234567890"); car.setColor("123456789012345678901234567890"); testService.addNewCar(car); ListcarList = testService.getAllCars(); assertEquals(1, carList.size()); testService.deleteAllCars(); } ... ......
Spring Boot版本:v2.3.1
pom.xml:
... .....org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java ... ...... org.springframework.boot spring-boot-starter-validation
Spring Hibernate配置(application-test.yml):
spring.datasource.url: jdbc:mysql://[主机URL]:3306/test
spring.datasource.username: [用户名]
spring.datasource.password: [密码]
spring.jpa.hibernate.ddl-auto: create-drop
spring.datasource.initialization-mode: always
MySQL版本:8.0.17
这个问题的原因是因为deleteAllCars()
没有将更改提交到数据库,而且测试方法中的所有操作都被包装在一个单一的事务中,因为事务正在传播。在测试类上添加以下注解即可解决此问题:(propagation = Propagation.NEVER)
。
这个问题的解决方法是将deleteAllCars()
操作的更改提交到数据库,并确保测试方法中的所有操作都在同一个事务中进行。可以通过在测试类上添加@Transactional
注解来实现这一点。
相关问题:如何在活动的Spring事务中将数据刷新到数据库中?
你好Sadhu,谢谢。实际上,我尝试在JUnit测试方法中添加事务注解,它可以按预期完成。所以我在想问题实际上是测试方法中的操作在删除完成之前就已经进行了读取?
这个链接可以给你一些线索:javacodegeeks.com/2011/12/…