Я хочу провести тестирование сущностей с помощью тестовых контейнеров PostgreSQL в моем приложении Spring boot 3.x. Сначала я пытаюсь вставить несколько записей о нарушении ограничений, затем несколько допустимых записей, а затем хочу удалить все записи, чтобы продолжить тестирование.
При удалении всех записей я получаю такую ошибку:
"строка была обновлена" или удалено другой транзакцией».
AFAIK JPA-тесты выполняются под транзакцией. К сожалению, база данных не входит в мою область действия, поэтому я не могу использовать @Version в сущности.
Это моя сущность:
@Entity
@Table(name= "E", schema = Const.SCHEME_NAME)
@Data
@NoArgsConstructor
@SuperBuilder
@EqualsAndHashCode
public class E {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false, updatable = false)
@EqualsAndHashCode.Include
private Long id;
@NotNull(message = "{name.not-blank}")
@Column(name="name", length = 150, nullable = false)
private String name;
мой репозиторий — это простой JpaRepository:
@Repository
public interface ERepository extends JpaRepository {
}
мой тест:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@ContextConfiguration(initializers = ETestApplication.TestContainersInitializer.class)
public class ETestApplication {
static class TestContainersInitializer implements
ApplicationContextInitializer {
public static List VALID=List.of(E.builder()
.name("asd")
.build()
);
public static List INVALID=List.of(E.builder()
.build()
);
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertyValues.of(
"spring.datasource.url="+ postgresService.getJdbcUrl(),
"spring.datasource.username="+ postgresService.getUsername(),
"spring.datasource.password="+ postgresService.getPassword())
.applyTo(applicationContext.getEnvironment());
}
@Container
private static PostgreSQLContainer postgresService = new
PostgreSQLContainer("postgres:16-alpine")
.withInitScript("sql/init.sql");
@LocalServerPort
protected int port;
@Autowired
protected ERepository repository;
@BeforeAll
public static void beforeAll() {
try {
postgresService.start();
}
catch (Exception e) {
e.printStackTrace();
}
}
@AfterAll
public static void afterAll() {
postgresService.stop();
}
protected void entityInsert(E e) {
E saved = repository.save(e);
Assertions.assertNotNull(saved);
E restored = repository.findById(saved.getId())
.orElseThrow(RuntimeException::new);
Assertions.assertNotNull(restored);
Assertions.assertEquals(saved, restored);
}
protected void entityUpdate(E e) {
E updated = repository.save(e);
Assertions.assertNotNull(updated);
Assertions.assertEquals(e.entity, updated);
}
protected void entityDelete(E e) {
repository.delete(e);
repository.findById(e.getId())
.ifPresent(d -> {
throw new RuntimeException("%s is not deleted".formatted(d));
});
}
@Test
@Order(1)
void agentServiceTest() {
INVALID.forEach(e -> {
Assertions.assertThrows(e.expectedException, () ->
repository.save(e.entity),
"constraints violated but no exception");
});
VALID.forEach(e -> {
entityInsert(e);
e.setName("bsd");
entityUpdate(e);
entityDelete(e.entity);
});
repository.deleteAll(); // Exception: Row was updated or deleted by another transaction
// continue testing...
}
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... ransaction
Весенние загрузочные тестовые контейнеры «строка была обновлена или удалена другой транзакцией» ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение