Spring Boot未执行data.sql中SQL语句的问题排查
我之前也碰到过一模一样的情况,结合你说的「表已正常创建、手动执行SQL无报错」的信息,大概率是下面几个常见原因之一,你可以逐个排查:
Spring Boot 2.5+版本的初始化模式限制
从Spring Boot 2.5开始,spring.sql.init.mode的默认值是embedded——意思是只有使用H2、HSQLDB这类嵌入式数据库时,才会自动执行data.sql初始化脚本。如果你的项目用的是MySQL、PostgreSQL这种外部数据库,默认是不会触发脚本执行的。
解决办法:在application.properties(或yml)里添加配置:spring.sql.init.mode=always要是想区分环境,比如只在开发环境开启,可以在
application-dev.properties里单独设置这个值,生产环境保持默认即可。data.sql的存放位置不对
Spring Boot默认只会扫描src/main/resources根目录下的data.sql(或者data-${platform}.sql),如果你把文件放到了子目录(比如src/main/resources/sql),就不会被自动加载。
解决办法:要么把data.sql移到src/main/resources根目录,要么通过配置指定脚本路径:spring.sql.init.data-locations=classpath:sql/data.sqlSQL语句的引号陷阱
你写的SQL里用了双引号包裹字符串:VALUES ("ROLE_USER", "default role for user"),但很多数据库(比如MySQL)默认不把双引号当作字符串边界符——双引号会被用来识别表名、列名这类标识符。如果你的数据库没开启ANSI_QUOTES模式,这条SQL其实会执行失败,导致Spring Boot跳过执行,但你手动执行的时候可能下意识改成了单引号?
解决办法:把SQL里的双引号改成单引号:insert into user_role(role, description) VALUES ('ROLE_USER', 'default role for user');JPA/Hibernate的初始化顺序冲突
如果你的项目用了JPA,并且设置了spring.jpa.hibernate.ddl-auto为create或create-drop,可能会出现Hibernate先创建表,但data.sql执行时机不对的情况。
解决办法:添加配置让data.sql在Hibernate建表之后执行:spring.jpa.defer-datasource-initialization=true
内容的提问来源于stack exchange,提问作者Krzysztof 303

