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=alwaysapplication-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
相关产品推荐
相关产品推荐

