修改spring.datasource.url后Spring JPA findAll返回空但原生查询有数据
表名大小写不匹配问题
本地MySQL如果运行在Windows/macOS环境,默认lower_case_table_names参数为1,表名大小写不敏感;而Amazon RDS的MySQL实例默认运行在Linux环境,lower_case_table_names默认值为0,表名大小写严格敏感。你的实体类显式指定@Table(name = "CATEGORY")使用全大写表名,若RDS中实际业务表名为小写category,JPA生成的SQL会查询不存在的大写表,刚好你配置了spring.jpa.hibernate.ddl-auto = update,Hibernate会自动在RDS中创建一个空的大写CATEGORY表,最终导致JPA查询返回空,而你手动执行原生SQL时大概率写的是小写表名,所以能返回正常数据。
验证方法:开启spring.jpa.show-sql = true后,复制控制台打印的JPA查询SQL直接在RDS中执行,确认是否返回空;同时检查RDS中是否同时存在大小写两个同名表。
解决方法:统一实体类表名配置和实际RDS表名的大小写,或者修改RDS的lower_case_table_names参数为1(注意该参数修改需要重建RDS实例,提前备份数据)。数据源连接的数据库实例不匹配
你配置的DB_URL中指定的数据库名称错误,导致应用连接到了RDS上一个空的数据库实例。你手动执行原生SQL时大概率连接的是正确的业务库,所以能查到数据,但应用实际连的是空库。
验证方法:在应用中注入JdbcTemplate执行SELECT DATABASE()打印当前连接的数据库名,和业务库名对比是否一致。
解决方法:修正DB_URL中的数据库名称,格式为jdbc:mysql://<rds地址>:3306/<业务库名>?<其他参数>。数据库用户权限/默认Schema配置错误
你配置的DB_USER用户的默认Schema不是业务表所在的Schema,或者该用户没有业务表的查询权限:JPA查询时默认使用用户的默认Schema,找不到对应表就返回空;而你手动执行SQL时可能指定了Schema前缀或者使用了高权限账号,所以能查到数据。
验证方法:在应用中用JdbcTemplate执行SELECT * FROM CATEGORY(和实体类表名大小写一致),看是否返回数据。
解决方法:给应用使用的数据库用户授予业务库的全部权限,或者修改用户的默认Schema为业务库。Hibernate方言不匹配
你没有显式配置Hibernate方言,RDS的MySQL版本和本地MySQL版本不一致,导致Hibernate自动识别的方言和实际数据库不兼容,生成的SQL语法不符合RDS MySQL的要求,查询无结果。
解决方法:在配置文件中添加对应RDS MySQL版本的方言配置,比如MySQL 8.0添加:spring.jpa.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect。
内容的提问来源于stack exchange,提问作者Mike Robideau

