簡體   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). 使用 H2 數據庫存儲內存數據,因為我需要為演示創建示例應用程序。

在 Resources 文件夾中,我確實有我的 SQL 文件。 當我將其命名為data.sql時,應用程序根本沒有啟動。 當我將此文件重命名為import.sql時,我的應用程序已啟動,但仍面臨多行插入問題。

數據插入 SQL 文件

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

當我的應用程序使用 Spring Boot 2.3.10.RELEASE 和 Spring Cloud Hoxton.SR5 運行時,這一切正常。

我也試過 JPA 和 Hibernate 的屬性來解決這個問題,但仍然沒有成功。 查找我使用的屬性如下:

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

由於更新了 Spring Boot 和 Spring Cloud 版本,我不確定是否有什么特別需要設置 H2 數據庫以用於多行插入。

看起來與 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]

更新

我已將我的 SQL 文件名恢復為 data.sql,然后我觀察到相同的 H2 數據庫異常即將到來,並且應用程序無法啟動。

在下面找到我得到的啟動執行的詳細信息:

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.

數據表實體 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
}

應用 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

重要更新

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並確保它在相同條件下失敗。 並且我確認我從data.sql加載數據時遇到了同樣的錯誤,它適用於較舊的 Spring 引導版本。

我剛剛將 SB 版本從2.5.0更新到2.3.10.RELEASE ,並且相同的代碼有效。

更多詳情

  1. data.sql文件與 Spring 引導版本2.3.10.RELEASE一起使用時, data.sql文件中的插入語句是多行且位於多行上。 它工作得很好。

  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.

  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. 因為它將每個新行上的語句視為 DDL。 在這種情況下,應用程序運行,但數據插入不發生。

     GenerationTarget encountered exception accepting command: Error executing DDL "('Data 3')" via JDBC Statement
  4. 第四種情況是data.sqldata.sql啟動版本2.5.0和數據中的插入語句時。根本不跑。

分享相同的示例代碼:源代碼可以在上面提到的4個條件下嘗試: demo-data-service

請建議。

您需要將此添加到應用程序配置中:

spring.jpa.defer-datasource-initialization=true

由於 Spring Boot 2.5.0,data.sql 默認在 schema 初始化之前執行。

也可以看看:

Spring 引導數據 JPA 帶 H2 和數據。sql - 找不到表

我發現自己使用 Spring boot 2.5.0 是不能在表名后添加換行符。 使用 Spring Boot 2.5.0,導入腳本應命名為import.sql

所以,這會引發異常

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

雖然這不是

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