简体   繁体   English

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

[英]Spring Boot 2.5.0, Spring Cloud 2020.0.2 and Hibernate 5.4.31 - H2 Database Multi Row Insert Failing

While Working on a Spring Boot Application with SB version 2.5.0, Spring Cloud (for Centralized Config 2020.0.2) The Hibernate version is 5.4.31 (I am not using a specific Hibernate version, it is as per Spring Boot compatibility). While Working on a Spring Boot Application with SB version 2.5.0, Spring Cloud (for Centralized Config 2020.0.2) The Hibernate version is 5.4.31 (I am not using a specific Hibernate version, it is as per Spring Boot compatibility). Using H2 database for in-memory data, as I need to create the sample application for demo.使用 H2 数据库存储内存数据,因为我需要为演示创建示例应用程序。

In the Resources folder, I do have my SQL file.在 Resources 文件夹中,我确实有我的 SQL 文件。 When I name it data.sql the application does not start at all.当我将其命名为data.sql时,应用程序根本没有启动。 When I renamed this file as import.sql , my application started but still facing issues for multi-row insertion.当我将此文件重命名为import.sql时,我的应用程序已启动,但仍面临多行插入问题。

Data Insert SQL File数据插入 SQL 文件

/* Data for Entity DataTable */
    INSERT INTO data_table (name) VALUES
    ('Data 1'),
    ('Data 2'),
    ('Data 3');

This was working perfectly fine when my Application is running with Spring Boot 2.3.10.RELEASE and Spring Cloud Hoxton.SR5.当我的应用程序使用 Spring Boot 2.3.10.RELEASE 和 Spring Cloud Hoxton.SR5 运行时,这一切正常。

I have also tried the properties of JPA and Hibernate to resolve this issue, but still no success.我也试过 JPA 和 Hibernate 的属性来解决这个问题,但仍然没有成功。 Find properties which I use are as below:查找我使用的属性如下:

spring.jpa.properties.hibernate.jdbc.batch_size=20
spring.jpa.properties.hibernate.order_inserts=true

Due to updating the Spring Boot and Spring Cloud version, I am not sure if there is anything I specifically need to set the H2 Database to work for Multi-Row insert.由于更新了 Spring Boot 和 Spring Cloud 版本,我不确定是否有什么特别需要设置 H2 数据库以用于多行插入。

Looks to be something relevant to Hibernate or H2 Database Issue.看起来与 Hibernate 或 H2 数据库问题有关。

WARN 7952 --- [           main] o.h.t.s.i.ExceptionHand lerLoggedImpl    : GenerationTarget encountered exception accepting command : Error executing DDL "('Data 2')" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "('Data 2')" via JDBC Statement
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.4.31.Final.jar!/:5.4.31.Final]

...
...
...

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "('Data 2'[*]),"; expected "(, WITH, SELECT, TABLE, VALUES"; SQL statement: ('Data 2'), [42001-200]

UPDATE更新

I have reverted my SQL file name to data.sql, and then I observed the same H2 database exception is coming and the application does not startup.我已将我的 SQL 文件名恢复为 data.sql,然后我观察到相同的 H2 数据库异常即将到来,并且应用程序无法启动。

Find below details for startup execution which I am getting:在下面找到我得到的启动执行的详细信息:

WARN 4720 --- [           main] ConfigServletWebServerApplicationContext : 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 #1 of URL [jar:file:/D:/Projects/SpringCloudDemoApp/spring-cloud-demo/target/demo-data-service-0.1.jar!/BOOT-INF/classes!/data.sql]: INSERT INTO data_table (name) VALUES ('Data 1'), ('Data 2'), ('Data 3'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "DATA_TABLE" not found; SQL statement: INSERT INTO data_table (name) VALUES ('Data 1'), ('Data 2'), ('Data 3') [42102-200]

...
...

ERROR 4720 --- [           main] o.s.boot.SpringApplication               : Application run failed

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 SQLscript statement #1 of URL [jar:file:/D:/Projects/SpringCloudDemoApp/spring-cloud-demo/target/demo-data-service-0.1.jar!/BOOT-INF/classes!/data.sql]: INSERT INTO data_table (name) VALUES ('Data 1'), ('Data 2'), ('Data 3'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "DATA_TABLE" not found; SQL statement: INSERT INTO data_table (name) VALUES ('Data 1'), ('Data 2'), ('Data 3') [42102-200]

Also please find my Entity class in case something wrong with this, but don't think so anything wrong with Entity class as it works well with older Spring Boot and Spring Cloud versions, but still sharing here. Also please find my Entity class in case something wrong with this, but don't think so anything wrong with Entity class as it works well with older Spring Boot and Spring Cloud versions, but still sharing here.

DataTable Entity Class数据表实体 Class

@Entity
@Table(name = "data_table")
public class DataTable {   

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "dataid")
    private Long id;

    @Column(name = "name", nullable = false, unique = true, length = 200)
    private String name;

    // Getter Setters will follow here
}

Application YML file应用 YML 文件

server:
    port: 9090
spring:
    datasource:
        url: jdbc:h2:mem:demodb
        driverClassName: org.h2.Driver
        username: scdemo
        password: scdemopass
    jpa:
        properties:
            hibernate:
                dialect: org.hibernate.dialect.H2Dialect
                jdbc:
                    batch_size: 20
                order_inserts: true
    h2:
        console:
            enabled: true
            path: /h2-console
            settings:
                trace: false

IMPORTANT UPDATE重要更新

I also tried the same, only with Spring Boot 2.5.0 and JPA, Hibernate with H2 Database, created a sample application which has only 4 files, The Spring Boot Application file to start and the Entity class, data.sql as above, and the application.yml for configurations and made sure that it fails for the same condition. I also tried the same, only with Spring Boot 2.5.0 and JPA, Hibernate with H2 Database, created a sample application which has only 4 files, The Spring Boot Application file to start and the Entity class, data.sql as above, and用于配置的application.yml并确保它在相同条件下失败。 And I confirm that I am getting the same error to load data from the data.sql to insert, which works well with the older Spring Boot Release.并且我确认我从data.sql加载数据时遇到了同样的错误,它适用于较旧的 Spring 引导版本。

I just updated the SB version from 2.5.0 to 2.3.10.RELEASE , and the same code worked.我刚刚将 SB 版本从2.5.0更新到2.3.10.RELEASE ,并且相同的代码有效。

More Details :更多详情

  1. When the data.sql file is used with Spring Boot Version 2.3.10.RELEASE and the Insert Statements in the data.sql file are multi-row and are on multiple lines.data.sql文件与 Spring 引导版本2.3.10.RELEASE一起使用时, data.sql文件中的插入语句是多行且位于多行上。 It works perfectly fine.它工作得很好。

  2. When data.sql renamed as an import.sql , with Spring Boot version 2.5.0 and the Insert Statements in the import.sql file are multi-row but it is expected to keep all values on the same line, this also works well. When data.sql renamed as an import.sql , with Spring Boot version 2.5.0 and the Insert Statements in the import.sql file are multi-row but it is expected to keep all values on the same line, this also works well.

  3. When data.sql renamed as an import.sql , with Spring Boot version 2.5.0 and the Insert Statements in the import.sql file are multi-row and are on multiple lines, this scenario fails. When data.sql renamed as an import.sql , with Spring Boot version 2.5.0 and the Insert Statements in the import.sql file are multi-row and are on multiple lines, this scenario fails. As it considers the statement on each new line as DDL.因为它将每个新行上的语句视为 DDL。 In this case Application Runs but the data insert does not take place.在这种情况下,应用程序运行,但数据插入不发生。

     GenerationTarget encountered exception accepting command: Error executing DDL "('Data 3')" via JDBC Statement
  4. And the 4th Case is when data.sql with Spring Boot version 2.5.0 and the Insert Statements in the data.sql file are multi-row and are on multiple lines, this scenario fails too At the time of Data Source Initialization and Application do not run at all.第四种情况是data.sqldata.sql启动版本2.5.0和数据中的插入语句时。根本不跑。

Sharing the Sample Code for the same: The source code can be tried with the 4 conditions mentioned above: demo-data-service分享相同的示例代码:源代码可以在上面提到的4个条件下尝试: demo-data-service

Please suggest.请建议。

You need to add this to the app config:您需要将此添加到应用程序配置中:

spring.jpa.defer-datasource-initialization=true

Since Spring Boot 2.5.0, the data.sql is executed before the schema initialization by default.由于 Spring Boot 2.5.0,data.sql 默认在 schema 初始化之前执行。

See also:也可以看看:

Spring Boot Data JPA with H2 and data.sql - Table not Found Spring 引导数据 JPA 带 H2 和数据。sql - 找不到表

What I found myself using Spring boot 2.5.0 is that you cannot add newline after table name.我发现自己使用 Spring boot 2.5.0 是不能在表名后添加换行符。 With Spring Boot 2.5.0, import script should be named import.sql使用 Spring Boot 2.5.0,导入脚本应命名为import.sql

So, this throws exception所以,这会引发异常

INSERT into
 TRANSACTIONS (id, account_id, amount, currency, type) VALUES (5, 2, -10.00, 'GBP', 'MONEY_TRANSFER')

while this doesn't虽然这不是

INSERT into TRANSACTIONS (id, account_id, amount, currency, type) VALUES (5, 2, -10.00, 'GBP', 'MONEY_TRANSFER')```

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM