Удалить не завершено перед вставкой - PullRequest
0 голосов
/ 04 августа 2020

Привет, я тестирую операцию удаления-вставки-удаления записи в MySQL с гибернацией Spring Boot, и я заметил проблему, когда кажется, что записи не удаляются полностью при вставке.

При кикстарте гибернации создаются 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) Удалить все записи

При выполнении утверждения обнаруживается, что список результатов все еще содержит последнюю запись, следовательно, утверждение не выполняется.

введите описание изображения здесь

Мне интересно, вызвано ли это тем, что операция удаления не была завершена до того, как произошла вставка.

Благодарю, если вы дадите некоторое представление об этом, большое спасибо.

Модель (Автомобиль. 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;
}

Репозиторий (CarReposiroty. 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<Car, Long> {

}

Сервис (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<Car> 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<Car> carList = testService.getAllCars();

    assertEquals(1, carList.size());

    testService.deleteAllCars();
}
...
......

Spring Boot v2.3.1

pom. xml

    ...
    .....
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    ...
    ......

Конфигурация спящего режима Spring (приложение-тест .yml)

spring.datasource.url: jdbc:mysql://[the host url]:3306/test
spring.datasource.username: [the username]
spring.datasource.password: [the password]
spring.jpa.hibernate.ddl-auto: create-drop
spring.datasource.initialization-mode: always

MySQL 8.0.17

1 Ответ

0 голосов
/ 04 августа 2020

Это связано с тем, что deleteAllCars() не фиксирует изменение в БД, и все действия внутри тестового метода заключены в одну транзакцию, поскольку транзакция распространяется. Добавьте ниже аннотацию к тестовому классу

@Transactional(propagation = Propagation.NEVER)

Отметьте также этот связанный вопрос Как перенести sh данные в базу данных внутри активной весенней транзакции?

...