![](/img/trans.png)
[英]Hibernate h2 database context loads tests Spring Boot 3.0.1
[英]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
,並且相同的代碼有效。
更多詳情:
當data.sql
文件與 Spring 引導版本2.3.10.RELEASE
一起使用時, data.sql
文件中的插入語句是多行且位於多行上。 它工作得很好。
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 and are on multiple lines, this scenario fails. 因為它將每個新行上的語句視為 DDL。 在這種情況下,應用程序運行,但數據插入不發生。
GenerationTarget encountered exception accepting command: Error executing DDL "('Data 3')" via JDBC Statement
第四種情況是data.sql
和data.sql
啟動版本2.5.0
和數據中的插入語句時。根本不跑。
分享相同的示例代碼:源代碼可以在上面提到的4個條件下嘗試: demo-data-service
請建議。
您需要將此添加到應用程序配置中:
spring.jpa.defer-datasource-initialization=true
由於 Spring Boot 2.5.0,data.sql 默認在 schema 初始化之前執行。
也可以看看:
我發現自己使用 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.