Man*_*dit 5 java hibernate jpa h2 spring-boot
在使用 SB 版本 2.5.0、Spring Cloud(用于集中配置 2020.0.2)开发 Spring Boot 应用程序时,Hibernate 版本为 5.4.31(我没有使用特定的 Hibernate 版本,它是根据 Spring Boot 兼容性)。使用 H2 数据库作为内存数据,因为我需要创建用于演示的示例应用程序。
在资源文件夹中,我确实有我的 SQL 文件。当我命名它时,data.sql应用程序根本不会启动。当我将此文件重命名为 时import.sql,我的应用程序启动了,但仍然面临多行插入问题。
数据插入SQL文件
/* Data for Entity DataTable */
INSERT INTO data_table (name) VALUES
('Data 1'),
('Data 2'),
('Data 3');
Run Code Online (Sandbox Code Playgroud)
当我的应用程序使用 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
Run Code Online (Sandbox Code Playgroud)
由于更新了 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]
Run Code Online (Sandbox Code Playgroud)
更新
我已将 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]
Run Code Online (Sandbox Code Playgroud)
另外,请找到我的实体类,以防出现问题,但不要认为实体类有任何问题,因为它与较旧的 Spring Boot 和 Spring Cloud 版本配合得很好,但仍然在这里共享。
数据表实体类
@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
}
Run Code Online (Sandbox Code Playgroud)
应用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
Run Code Online (Sandbox Code Playgroud)
重要更新
我也尝试了相同的操作,仅使用 Spring Boot 2.5.0 和 JPA,Hibernate 和 H2 数据库,创建了一个示例应用程序,该应用程序只有 4 个文件,即要启动的 Spring Boot 应用程序文件和实体类,data.sql如上所述,以及application.yml配置并确保它在相同的条件下失败。我确认我在从data.sql插入加载数据时遇到了相同的错误,这与旧的 Spring Boot 版本配合良好。
我刚刚将 SB 版本从 更新到2.5.0,2.3.10.RELEASE并且相同的代码有效。
更多细节:
当该data.sql文件与 Spring Boot 版本一起使用2.3.10.RELEASE且文件中的 Insert 语句data.sql是多行且位于多行时。它工作得很好。
当使用 Spring Boot 版本 2.5.0data.sql重命名为 时import.sql,文件中的插入语句import.sql是多行的,但预计将所有值保留在同一行上,这也可以很好地工作。
当data.sql重命名为import.sqlSpring Boot 版本2.5.0且文件中的 Insert 语句import.sql是多行且位于多行时,这种情况会失败。因为它将每个新行上的语句视为 DDL。在这种情况下,应用程序会运行,但不会发生数据插入。
GenerationTarget encountered exception accepting command : Error executing DDL "('Data 3')" via JDBC Statement
Run Code Online (Sandbox Code Playgroud)
第四种情况是,当data.sql使用 Spring Boot 版本2.5.0并且文件中的插入语句data.sql是多行且位于多行时,这种情况也会失败。在数据源初始化时,应用程序根本不运行。
共享示例代码:满足上述 4 个条件即可尝试源代码: demo-data-service
请建议。
您需要将其添加到应用程序配置中:
spring.jpa.defer-datasource-initialization=true
Run Code Online (Sandbox Code Playgroud)
从Spring Boot 2.5.0开始,data.sql默认在schema初始化之前执行。
也可以看看:
使用 H2 和 data.sql 的 Spring Boot Data JPA - 找不到表
| 归档时间: |
|
| 查看次数: |
2779 次 |
| 最近记录: |