【问题标题】:Why is my import.sql file not automatically running?为什么我的 import.sql 文件没有自动运行?
【发布时间】:2019-12-29 18:13:23
【问题描述】:

正在开发 java spring boot 应用程序。我们的 postgres 数据库是容器化的。我可以让休眠自动创建表,但我不能让它自动运行 import.sql 文件。你能帮我弄清楚这是怎么回事吗?

这里是 build.gradle 文件:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath('org.springframework.boot:spring-boot-gradle-plugin:2.1.6.RELEASE')
    }
}


apply plugin: 'application'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

mainClassName = 'idealab.IdeaLabMain'

bootJar {
    baseName = 'idealab'
    excludeDevtools = false //TODO(e-carlin): In production this should be removed
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile('org.springframework.boot:spring-boot-devtools') // TODO(e-carlin): Make sure this isn't pulled in in the production jar
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('org.springframework.boot:spring-boot-starter-web')
    implementation('org.postgresql:postgresql')
    testCompile('junit:junit')
}

这是 application.properties 文件:

logging.level.org.hibernate=DEBUG
debug=true

spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=docker
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
hibernate.hbm2ddl.auto=create # TODO(e-carlin): This will wipe away the
                                     # database data. Good for dev not for prod
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

这是位于 src/main/resources 中的 import.sql 文件:

INSERT INTO color_type (color) VALUES ('blue'),('green'),('purple'),('red');

下面是这个模型的一个例子:

package idealab.api.model;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;



@Entity
@Table(name = "color_type")
public class ColorType {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @OneToMany(targetEntity=PrintModel.class, mappedBy="colorTypeId")   
    private Set<PrintModel> printModel;

    @Column(name = "color", nullable = false)
    private String color;

    public ColorType(Integer id, String color) {

        this.color = color;
    }

    //getters and setters
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

感谢您提供的任何帮助!

【问题讨论】:

    标签: postgresql hibernate spring-boot docker gradle


    【解决方案1】:

    添加以下属性后尝试,

    spring.datasource.initialization-mode=always
    

    如果您使用的是 Spring boot 2,则数据库初始化仅适用于嵌入式数据库(H2、HSQLDB、...)。如果你也想将它用于其他数据库,你需要更改 spring.datasource.initialization-mode 属性:

    如果不起作用,请将 sql 文件更改为 data.sql 并尝试。

    参考请查看spring-doc

    【讨论】:

    • 好吧,我猜import.sql是与springboot无关的hibernate原生特性。如果 hibernate.hbm2ddl.autocreatecreate-drop ,它将被执行。与嵌入式数据库无关...
    【解决方案2】:

    import.sql 是 Hibernate 原生功能,只有在 hibernate.hbm2ddl.auto 设置为 createcreate-drop 时才会执行。

    但现在你正在设置:

    spring.jpa.generate-ddl=true
    hibernate.hbm2ddl.auto=create 
    
    • spring.jpa.generate-ddl=true 将在幕后设置hibernate.hbm2ddl.auto=update
    • hibernate.hbm2ddl.auto=create 无效并且没有任何效果,因为所有有效的 springboot JPA 属性都应该以 spring.jpa 开头

    所以最后,hibernate.hbm2ddl.auto 将被设置为 update,因此import.sql 将不会被执行。

    您只需将hibernate.hbm2ddl.auto=create 更改为:即可修复它:

    spring.jpa.properties.hibernate.hbm2ddl.auto=create
    

    注意:spring.jpa.generate-ddl 将被 spring.jpa.properties.hibernate.hbm2ddl.auto 覆盖,因此您可以简单地删除它。

    【讨论】:

    • 感谢您的回答!我已将其切换为您所说的内容,但仍未加载数据。有什么想法吗?
    • @moosespirit94,对不起。我错过了 properties 这个词。它应该是 spring.jpa.properties.hibernate.hbm2ddl.auto=create 。另外请确保 "create" 后没有空格。如果您只是复制我的原始答案,它将包含空间,但休眠不会自动修剪该空间并将其视为无效值。我只是在本地尝试,它按预期工作。
    • 我收到此错误:org.springframework.beans.factory.BeanCreationException:在类路径资源 [org/springframework/boot/autoconfigure/orm/jpa/ 中定义名称为“entityManagerFactory”的 bean 创建时出错HibernateJpaConfiguration.class]: init 方法调用失败;嵌套异常是 javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory;嵌套异常是 java.lang.IllegalArgumentException: Unrecognized legacy hibernate.hbm2ddl.auto value : create
    • 解决了我的问题 - 创建后我有一个空间。非常感谢您的帮助!
    • 很高兴听到。因此,如果您发现它对您有用,请考虑投票或接受我的答案? ?
    【解决方案3】:

    我们有这些属性来创建记录并将其插入表中。由于您只需要插入记录即可删除spring.datasource.schema

    spring.datasource.schema= # Schema (DDL) script resource references.
    spring.datasource.data= # Data (DML) script resource references.
    
    • 无需更改 SQL 文件名
    • 可以将模式生成和插入保持在同一个文件中
    • 可以指定多个文件

      spring.datasource.data = classpath:/abc.sql,classpath:/abc2.sql

    注意:

    • 对于同一个文件中的模式生成和插入,不要使用spring.datasource.data,我们必须使用spring.datasource.schema
    • 将所有文件保存在 src/main/resources
    • 设置spring.datasource.initialization-mode=always

    logging.level.org.hibernate=DEBUG
    debug=true
    
    spring.datasource.initialization-mode=always
    spring.datasource.platform=postgres
    spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
    spring.datasource.username=postgres
    spring.datasource.password=docker
    spring.datasource.data = classpath:/import.sql
    
    spring.jpa.database=POSTGRESQL
    spring.jpa.show-sql=true
    spring.jpa.generate-ddl=true
    spring.jpa.hibernate.ddl-auto=create 
    spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      • 2013-04-03
      • 1970-01-01
      • 2020-08-21
      • 2014-07-03
      • 2017-12-01
      • 1970-01-01
      相关资源
      最近更新 更多