Spring Boot应用本地正常,部署Heroku后报SQL语法错误求助
这个问题我之前帮同事排查过类似的,核心不是SQL语法有问题——毕竟本地能跑通就说明语法没问题,问题出在本地和Heroku PostgreSQL环境的差异上,下面拆解原因和解决办法:
常见原因
Heroku数据库中没有创建
products表
本地开发时,你可能配置了spring.jpa.hibernate.ddl-auto=create或update,让Hibernate自动帮你生成了products表;但Heroku作为生产环境,这种自动建表的配置通常不会生效(或者你没在Heroku的配置里开启),导致数据库里根本没有这个表,自然查不到。PostgreSQL的大小写敏感坑
PostgreSQL默认对标识符(表名、列名)是区分大小写的,但如果创建表时没加双引号,它会自动把表名转成小写。比如你本地创建表时写的是CREATE TABLE Products(没加引号),PostgreSQL会存成products;但如果不小心在Heroku上创建表时加了双引号(比如CREATE TABLE "Products"),那表名就是大写的Products,这时候你查public.products就会报“relation不存在”。Schema配置差异
虽然你SQL里指定了public.products,但极少数情况下Heroku的PostgreSQL默认Schema可能不是public(比如你手动修改过),不过这种情况概率很低。
解决步骤
先确认Heroku数据库里的表状态
打开终端,用Heroku CLI连接你的数据库:heroku pg:psql -a 你的应用名称然后输入
\dt命令,查看所有表。如果看不到products,那就是表没创建;如果看到的是Products(大写),那就是大小写问题。针对表不存在的情况
- 推荐用数据库迁移工具(比如Flyway或Liquibase)来管理表结构,生产环境用自动建表太不安全。写好建表的SQL脚本,配置Flyway后部署到Heroku,它会自动执行脚本创建表。
- 临时解决的话,也可以直接在Heroku的psql终端里执行建表语句:
CREATE TABLE products ( id INT PRIMARY KEY, name VARCHAR(255), price FLOAT, image VARCHAR(255), description TEXT );
针对大小写问题的情况
如果你Heroku上的表名是大写的Products,那修改你的SQL语句,给表名加上双引号:jdbcTemplate.query( "SELECT id, name, price, image, description FROM public.\"Products\";", (rs, rowNum) -> new Product(rs.getInt("id"), rs.getString("name"), rs.getFloat("price"), rs.getString("image"), rs.getString("description")) ).forEach(product -> productsList.add(product));或者重新在Heroku上创建小写的
products表,保持和本地一致。检查配置一致性
确认你的本地和Heroku的数据库配置(比如spring.datasource.url、spring.datasource.username等)是否正确,尤其是Heroku的数据库URL是自动注入的,不要手动硬编码。
内容的提问来源于stack exchange,提问作者Hardok

