Spring Boot 2 - H2 数据库 - @SpringBootTest - org.h2.jdbc.JdbcSQLException 失败:表已存在

Posted

技术标签:

【中文标题】Spring Boot 2 - H2 数据库 - @SpringBootTest - org.h2.jdbc.JdbcSQLException 失败:表已存在【英文标题】:Spring Boot 2 - H2 Database - @SpringBootTest - Failing on org.h2.jdbc.JdbcSQLException: Table already exists 【发布时间】:2018-06-02 08:59:49 【问题描述】:

无法使用用于使用 schema.sql 创建表的脚本来测试 Spring Boot 和 H2。

所以,我设置了以下属性:

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 运行测试时,我的 Repository 测试通过了,但我的 Service 测试失败,表明它正在尝试创建表,而表已经存在:

引发异常:

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

代码已设置好并准备好重新创建场景。自述文件包含所有信息-> https://github.com/tekpartner/learn-spring-boot-data-jpa-h2

【问题讨论】:

【参考方案1】:

您可以尝试其他两种可能的解决方案:

    在创建表之前,在 schema.sql 中添加 drop table if exists [tablename]。 将语句从 CREATE TABLE 更改为 CREATE TABLE IF NOT EXISTS

【讨论】:

您的解决方案最适合我,因为它还解决了该问题之后出现的问题,该问题与数据插入导致唯一键冲突有关。谢谢你。 对于数据插入唯一键冲突我使用***.com/a/19768315/4082981【参考方案2】:

如果测试是单独运行的,它们就会通过。我认为问题是由于 schema.sql 对同一个数据库执行了两次。第二次失败,因为表已经存在。

作为一种解决方法,您可以在application.properties 中设置spring.datasource.continue-on-error=true

另一种选择是在适当的地方添加@AutoConfigureTestDatabase 注释,以便为每个测试使用唯一的嵌入式数据库。

【讨论】:

使用@AutoConfigureTestDatabase 解决了它。感谢您抽出宝贵时间。 同样,使用@AutoConfigureTestDatabase 解决了它。我为此苦苦挣扎了 3 个小时,谢谢 谢谢,这两个属性也解决了我的问题。但是,为什么 SQL 会在同一个应用程序上下文中执行两次?

以上是关于Spring Boot 2 - H2 数据库 - @SpringBootTest - org.h2.jdbc.JdbcSQLException 失败:表已存在的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2.x 实践记:H2 Database

Spring Boot 2.x 实践记:H2 Database

Spring Boot 2 - H2 数据库 - @SpringBootTest - org.h2.jdbc.JdbcSQLException 失败:表已存在

Spring Boot 2.5.0、Spring Cloud 2020.0.2 和 Hibernate 5.4.31 - H2 数据库多行插入失败

如何在 Spring Boot 中启用 H2 数据库服务器模式

内存数据库spring-boot中的h2