gpt4 book ai didi

spring-boot - 用于测试 Spring Boot 应用程序的初始化 H2 数据库期间出现异常 "org.h2.jdbc.JdbcSQLSyntaxErrorException:Table "NAME“未找到”

转载 作者:行者123 更新时间:2023-12-05 03:38:05 24 4
gpt4 key购买 nike

我编写了带有@SpringBootTest 注释的集成测试。为了运行测试,我将数据从测试资源中的 data.sql 插入到 H2 数据库。

我遇到的情况是第一次测试成功运行,多次后出现错误,提示 H2 无法在表中插入数据,因为未找到该表。每次下一次启动测试时,都会出现不同的原始错误。在同一个日志中,我看到在异常发生之前创建了这个表并且其他插入操作成功执行。我看到我的 5 个测试中有 4 个是绿色的,一个是红色的。它可以是不同时间的不同测试。

重新启动 IDE 会使测试再次成功运行 3-4 次。之后,错误返回。

我尝试将@DirtiesContext() 与我的测试类和测试方法一起使用,但它没有解决问题。

我猜测问题的根源可能在于我初始化数据库的方式。对于这两个数据库,我都使用一个 data.sql 文件的引用。我没能找到一种方法将它们分成不同的 *.sql 文件。

第二个猜测是在创建表之前开始向数据库中插入数据。我现在通过将所有插入移动到测试代码中来检查这个理论。但是我不确定它是否会有所帮助,因为我播报了表是在插入开始之前创建的日志。

我在每次测试运行前都使用“mvn clean”。

如果您提出解决此问题的建议,我将不胜感激。

我的实体:

@Entity
@Table(name = "entity1", schema = "schema1")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SomeEntityClass extends GenericEntity<Long> { ...}


@MappedSuperclass
public abstract class GenericEntity<ID extends Serializable> implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column

protected ID id;

//getter, setter
}

在我的 data.sql 文件中初始化如下所示:

create schema if not exists schema1;
create schema if not exists schema2;

drop table if exists schema1.table1;
create table schema1.table1
(....structure of the table...)

drop table if exists schema2.table2;
create table schema2.table2
(....structure of the table...)

INSERT INTO schema1.table1
(...)
VALUES (...)

... many insertions


INSERT INTO schema2.table2
(...)
VALUES (...)

... many insertions

这是test/resources中application.properties中的H2配置:

# The first database
spring.datasource.url=jdbc:h2:mem:database01;INIT=RUNSCRIPT FROM 'src/test/resources/data.sql'
spring.datasource.username=user1
spring.datasource.password=abc
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.generate-ddl=true

# The second database
spring.datasource.security.url=\
jdbc:h2:mem:dbo_security_db:database02;INIT=RUNSCRIPT FROM 'src/test/resources/data.sql'
spring.datasource.security.username=user1
spring.datasource.security.password=abc
spring.datasource.security.driver-class-name=org.h2.Driver

spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true

错误日志:

08-09-2021 09:00:08.729 DEBUG [o.s.jdbc.datasource.init.ScriptUtils] - 0 returned as update count for SQL: create table schema1.table1( ….)
08-09-2021 09:00:08.730 DEBUG [o.s.jdbc.datasource.init.ScriptUtils] - 1 returned as update count for SQL: INSERT INTO schema1.table1(...) VALUES ()
///...other insertions into this table performed well
08-09-2021 09:00:08.735 WARN [o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #36 of URL [file:/home/nikiforov-java/Documents/.../target/test-classes/data.sql]: INSERT INTO schema1.table1(...) VALUES (...); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "TABLE1" not found; SQL statement: ...

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
08-09-2021 09:00:08.782 ERROR [o.s.boot.SpringApplication] - Application run failed

最佳答案

将此属性添加到 application.properties:

spring.jpa.defer-datasource-initialization=true

根据 Spring Boot 2.5 RELEASE notes :

By default, data.sql scripts are now run before Hibernate is initialized. This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase. If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true.

关于spring-boot - 用于测试 Spring Boot 应用程序的初始化 H2 数据库期间出现异常 "org.h2.jdbc.JdbcSQLSyntaxErrorException:Table "NAME“未找到”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69097912/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com