You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot PostgreSQL环境下data.sql重复执行的问题咨询

解决PostgreSQL环境下data.sql重复执行的问题

当前配置

application.properties:

spring.datasource.url=jdbc:postgresql://localhost:5432/webdev_simplified
spring.datasource.username=postgres
spring.datasource.password=postgres

spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG

spring.sql.init.mode=always
spring.jpa.defer-datasource-initialization=true
#spring.datasource.initialization-mode=always

问题现象

执行 mvn clean package 后,PostgreSQL中已创建表且data.sql执行完成(可通过select * from cart_item查询到数据);但运行 java -jar target/app.jar 时,data.sql再次执行,导致数据重复插入(主键递增)。而相同配置在MySQL环境下无此问题。

阻止data.sql重复执行的方法

1. 调整spring.sql.init.mode配置

  • 若仅需在嵌入式数据库(如H2)初始化时执行data.sql,修改为:
    spring.sql.init.mode=embedded
    
  • 若完全不需要自动执行data.sql,修改为:
    spring.sql.init.mode=never
    

2. 通过SQL语句避免重复插入(临时兼容方案)

在data.sql的插入语句中添加主键冲突处理逻辑,同时开启错误忽略:

spring.sql.init.continue-on-error=true

示例插入语句:

INSERT INTO cart_item (id, name, quantity) VALUES (1, 'Item1', 2) ON CONFLICT (id) DO NOTHING;

3. 分环境配置区分打包与运行阶段

创建多环境配置文件,分离打包和运行时的初始化规则:

  • application-dev.properties(开发/打包阶段用):
    spring.sql.init.mode=always
    
  • application-prod.properties(运行jar包时用):
    spring.sql.init.mode=never
    

运行jar时指定生产环境:

java -jar target/app.jar --spring.profiles.active=prod

MySQL与PostgreSQL的差异原因

Spring Boot中spring.sql.init.mode=always会在数据源初始化时触发data.sql执行,但两者在初始化标记的处理逻辑上有差异:

  • MySQL:当spring.jpa.hibernate.ddl-auto=update时,Hibernate更新表结构后,Spring会记录初始化完成的标记,后续启动不会重复执行data.sql。
  • PostgreSQL:受事务机制和Hibernate对PostgreSQL的DDL处理逻辑影响,Spring的初始化标记未被正确持久化或识别,导致每次启动都会重新执行data.sql。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:12:25