Spring Boot 2 — база данных H2 — @SpringBootTest — сбой в org.h2.jdbc.JdbcSQLException: таблица уже существует

Не удалось протестировать Spring Boot и H2 со скриптом для создания таблицы с использованием schema.sql.

Итак, что происходит, так это то, что у меня установлены следующие свойства:

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.initialization-mode=always
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.platform=h2
spring.datasource.url=jdbc:h2:mem:city;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

и я ожидаю, что таблицы будут созданы с использованием schema.sql. Приложение отлично работает, когда я запускаю gradle bootRun. Однако, когда я запускаю тесты с помощью gradle test, мои тесты для репозитория проходят успешно, но тест для моей службы не работает, заявляя, что он пытается создать таблицу, когда таблица уже существует:

Возникло исключение:

Caused by: org.h2.jdbc.JdbcSQLException: Table "CITY" already exists;             
SQL statement:
CREATE TABLE city ( id BIGINT NOT NULL, country VARCHAR(255) NOT NULL, map VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, state VARCHAR(2555) NOT NULL, PRIMARY KEY (id) ) [42101-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.command.ddl.CreateTable.update(CreateTable.java:117)
at org.h2.command.CommandContainer.update(CommandContainer.java:101)
at org.h2.command.Command.executeUpdate(Command.java:260)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:192)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:164)
at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:471)
... 105 more

Код настроен и готов воссоздать сценарий. README содержит всю информацию -> https://github.com/tekpartner/learn-spring-boot-data-jpa-h2


person Tora Tora Tora    schedule 19.12.2017    source источник


Ответы (2)


Если тесты выполняются индивидуально, они проходят. Я думаю, что проблема связана с тем, что schema.sql выполняется дважды для одной и той же базы данных. Во второй раз это не удается, поскольку таблицы уже существуют.

В качестве обходного пути вы можете установить spring.datasource.continue-on-error=true в application.properties.

Другой вариант — добавить аннотацию @AutoConfigureTestDatabase, где это уместно, чтобы для каждого теста использовалась уникальная встроенная база данных.

person Madhura Bhave    schedule 20.12.2017
comment
Использование @AutoConfigureTestDatabase решило эту проблему. Спасибо, что нашли время. - person Tora Tora Tora; 20.12.2017
comment
То же самое, использование @AutoConfigureTestDatabase решило эту проблему. Я боролся с этим 3 часа, спасибо - person HMarteau; 25.03.2019
comment
Спасибо, эти два свойства решили и мою проблему. Но почему SQL-запросы выполняются дважды в одном и том же контексте приложения? - person Umesh; 30.09.2020

Есть 2 других возможных решения, которые вы можете попробовать:

  1. Добавьте drop table if exists [tablename] в ваш schema.sql перед созданием таблицы.
  2. Измените оператор с CREATE TABLE на CREATE TABLE IF NOT EXISTS
person the hand of NOD    schedule 19.12.2018
comment
Ваше решение сработало для меня лучше всего, потому что оно также решает проблему, возникающую после этого, которая связана с вставкой данных, вызывающей конфликты уникальных ключей. Спасибо за это. - person cristianoms; 08.12.2019
comment
Для вставки данных с уникальными конфликтами ключей я использовал stackoverflow.com/a/19768315/4082981 - person salerokada; 21.07.2020