spring-data-jpa 2.5.0升级后, Boot 数据源初始化错误,data.sql脚本出现错误

9bfwbjaz  于 2022-11-10  发布在  Spring
关注(0)|答案(5)|浏览(229)

我有一个配置了Sping Boot 和Spring Data JPA的项目。
我的项目包含以下data.sql初始化脚本(我刚刚开始开发我的应用程序,这就是我使用嵌入式H2数据库的原因):

INSERT INTO Project(id, name) VALUES (1, 'Project 1');

我定义了以下实体:

@Entity
public class Project {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    protected Project() {
    }

    public Project(String name) {
        this.name = name;
    }
    // ...
}

我没有任何其他配置/设置。

ERROR 5520 ---[  restartedMain] 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 SQL script statement #1 of URL [file:/C:/path/project/target/classes/data.sql]: INSERT INTO Project(id, name) VALUES (1, 'Project 1'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "PROJECT" not found; SQL statement:
INSERT INTO Project(id, name) VALUES (1, 'Project 1') [42102-200]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602)
...
Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of URL [file:/C:/path/project/target/classes/data.sql]: INSERT INTO Project(id, name) VALUES (1, 'Project 1'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "PROJECT" not found; SQL statement:
INSERT INTO Project(id, name) VALUES (1, 'Project 1') [42102-200]
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:622)
    at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:254)
...
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "PROJECT" not found; SQL statement:
INSERT INTO Project(id, name) VALUES (1, 'Project 1') [42102-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:453)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)

当然,在升级之前,应用程序启动得很好。

o0lyfsai

o0lyfsai1#

TL;DR

Sping Boot 似乎已经修改了它使用2.5.0的SQL脚本初始化数据源的方式。
可以通过在项目中包含以下特性来解决此问题:

spring:
  jpa:
    defer-datasource-initialization: true

的解释:
2.5.0中引入的更改中,data.sql脚本现在似乎在Hibernate初始化之前执行:
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes#hibernate-and-datasql
由于我依赖ORM机制(即Hibernate)从实体定义创建模式,因此在执行初始化SQL脚本时,数据库表并不存在。

bbuxkriu

bbuxkriu2#

Add "spring.jpa.defer-datasource-initialization = true" to application.properties file.
原因:默认情况下,data.sql脚本现在在Hibernate初始化之前运行。这使基于脚本的基本初始化的行为与Flyway和Liquibase的行为一致。如果要使用data.sql填充由Hibernate创建的模式,请将spring.jpa.defer-datasource-initialization设置为true。虽然不建议混合使用数据库初始化技术,这还将允许您在通过data.sql填充Hibernate创建的模式之前使用schema.sql脚本构建该模式。
来源:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes#hibernate-and-datasql

envsm3lx

envsm3lx3#

希望它能帮助一些人。我也有同样的问题,我的data.sql文件没有被选中,所以只生成空白表。我使用了下面提到的属性,它对我很有效:

spring.sql.init.mode=always
    spring.datasource.url= jdbc:mysql://${MYSQL_CONTAINER_NAME:localhost}:3306/${MYSQL_DATABASE:uber}
    spring.datasource.username=${MYSQL_USER:boca-user}
    spring.datasource.password=${MYSQL_PASSWORD:boca-password}
    spring.datasource.initialization-mode=always
    spring.jpa.show-sql=true
    spring.jpa.defer-datasource-initialization = true
    spring.jpa.hibernate.ddl-auto=update
vptzau2j

vptzau2j4#

似乎可以让ORM供应商为您创建模式,然后通过data.sql导入数据
要实现这一点,还需要另一个属性:spring.sql.init.mode: always
我的全部相关属性集如下:

spring:
  sql.init.mode: always
  datasource:
    url: jdbc:postgresql://localhost:5432/products
    username: 
    password: 
  jpa:
    defer-datasource-initialization: true
    hibernate:
      ddl-auto: create-drop
    database-platform: org.hibernate.dialect.PostgreSQLDialect
6rqinv9w

6rqinv9w5#

我遇到了类似的问题,我只是添加了**@Entity(name=“table_name”)**,错误就解决了。
application.properties 文件内容:

spring.sql.init.mode=always
spring.jpa.defer-datasource-initialization = true
spring.h2.console.enabled=true
spring.sql.init.platform=h2
spring.datasource.url=jdbc:h2:mem:ToDo
spring.datasource.username=sa
spring.datasource.password=

相关问题