删除未完成之前的插入操作

14 浏览
0 Comments

删除未完成之前的插入操作

你好,我正在使用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 List getAllCars() {
        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);
    List carList = 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

0
0 Comments

这个问题的原因是因为deleteAllCars()没有将更改提交到数据库,而且测试方法中的所有操作都被包装在一个单一的事务中,因为事务正在传播。在测试类上添加以下注解即可解决此问题:(propagation = Propagation.NEVER)

这个问题的解决方法是将deleteAllCars()操作的更改提交到数据库,并确保测试方法中的所有操作都在同一个事务中进行。可以通过在测试类上添加@Transactional注解来实现这一点。

相关问题:如何在活动的Spring事务中将数据刷新到数据库中?

你好Sadhu,谢谢。实际上,我尝试在JUnit测试方法中添加事务注解,它可以按预期完成。所以我在想问题实际上是测试方法中的操作在删除完成之前就已经进行了读取?

这个链接可以给你一些线索:javacodegeeks.com/2011/12/…

0