You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot如何正确配置PostgreSQL通过schema.sql和data.sql初始化数据?

Spring Boot + PostgreSQL 启动时自动初始化表结构与数据的正确配置

问题描述

我正在开发一个使用PostgreSQL的Spring Boot项目,希望应用启动时自动创建表并插入初始数据。

当前application.properties配置:

spring.datasource.url=jdbc:postgresql://localhost:5432/progra3db
spring.datasource.username=progra3
spring.datasource.password=progra3
spring.datasource.driver-class-name=org.postgresql.Driver  
spring.sql.init.mode=always
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

schema.sql表定义:

CREATE TABLE IF NOT EXISTS nodes (
    id BIGINT PRIMARY KEY,
    code VARCHAR(50),
    name VARCHAR(100),
    type VARCHAR(50),
    description TEXT,
    parent_id BIGINT
);

data.sql测试数据:

INSERT INTO nodes (id, code, name, type, description, parent_id) VALUES
  (1, '1', 'Assets', 'GROUP', 'Company assets', NULL),
  (2, '1.1', 'Current Assets', 'GROUP', 'Short-term assets', 1),
  (3, '1.1.1', 'Cash', 'ACCOUNT', 'Cash available', 2);

启动应用后项目可运行,但有时数据未插入或表未按预期创建。尝试修改spring.jpa.hibernate.ddl-autononeupdatecreate,仍不清楚使用schema.sqldata.sql时的正确配置方式。


正确配置方案

1. 调整核心配置项

更新application.properties为如下配置:

# 数据源基础配置
spring.datasource.url=jdbc:postgresql://localhost:5432/progra3db
spring.datasource.username=progra3
spring.datasource.password=progra3
spring.datasource.driver-class-name=org.postgresql.Driver  

# SQL初始化核心配置
spring.sql.init.mode=always
# 默认扫描classpath下的schema.sql和data.sql,自定义路径可取消下方注释配置
# spring.sql.init.schema-locations=classpath:schema.sql
# spring.sql.init.data-locations=classpath:data.sql

# JPA/Hibernate配置
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
# 关键:延迟JPA初始化,避免与SQL脚本执行顺序冲突
spring.jpa.defer-datasource-initialization=true

2. 配置关键说明

  • spring.sql.init.mode=always:强制应用启动时执行schema.sqldata.sql,无论数据库是否已有数据或表结构。若仅需首次初始化,可改为embedded(仅针对嵌入式数据库)。
  • spring.jpa.hibernate.ddl-auto=none:完全禁用Hibernate的自动DDL生成,避免其与自定义schema.sql的表结构定义冲突。
  • spring.jpa.defer-datasource-initialization=true:解决执行顺序问题——Spring Boot默认先初始化JPA,再执行SQL脚本,会导致Hibernate尝试映射实体时表尚未创建。开启该配置后,会先执行SQL初始化脚本,再初始化JPA,确保表创建完成后再处理数据插入和实体映射。

3. 额外注意事项

  • SQL文件位置:确保schema.sqldata.sql放在src/main/resources目录下,这是Spring Boot默认扫描路径。若文件路径不同,需通过spring.sql.init.schema-locationsspring.sql.init.data-locations指定。
  • 表创建的幂等性:你的schema.sql已使用CREATE TABLE IF NOT EXISTS,可避免重复创建表时的报错,保持该写法即可。
  • 数据插入的幂等性:当前INSERT语句在表已有数据时会因主键冲突报错。如需重复启动时不报错,可修改为幂等插入:
INSERT INTO nodes (id, code, name, type, description, parent_id) VALUES
  (1, '1', 'Assets', 'GROUP', 'Company assets', NULL),
  (2, '1.1', 'Current Assets', 'GROUP', 'Short-term assets', 1),
  (3, '1.1.1', 'Cash', 'ACCOUNT', 'Cash available', 2)
ON CONFLICT (id) DO NOTHING;

内容的提问来源于stack exchange,提问作者Angello Escobar

火山引擎 最新活动