相同Spring Boot环境下JPQL查询缺失ID字段的原因排查
问题描述
在JPA Repository中定义了如下数据查询方法:
@Query( "SELECT s FROM Site s " + "LEFT JOIN FETCH s.siteType " + "LEFT JOIN FETCH s.variables " + "LEFT JOIN FETCH s.parameters") List<Site> findWithDetails();
本地与同事环境均使用Spring Boot 2.7.0(内置Spring Data 2.7.0)版本,本地环境下该JPQL可正常翻译为完整SQL,所有实体的ID字段、关联外键字段均被正常查询,SQL可正常执行,翻译生成的SQL如下:
select site0_.id_site as id_site1_37_0_, sitetype1_.id_site_type as id_site_1_39_1_, variables2_.id_variable as id_varia1_50_2_, parameters3_.id_site_param as id_site_1_38_3_, site0_.active as active2_37_0_, site0_.coord as coord3_37_0_, site0_.name as name4_37_0_, site0_.short_name as short_na5_37_0_, site0_.id_site_type as id_site_7_37_0_, site0_.source as source6_37_0_, sitetype1_.display_name as display_2_39_1_, sitetype1_.marker_default_color as marker_d3_39_1_, sitetype1_.marker_fa_icon as marker_f4_39_1_, sitetype1_.marker_fa_icon_color as marker_f5_39_1_, sitetype1_.marker_fa_icon_prefix as marker_f6_39_1_, sitetype1_.marker_shape as marker_s7_39_1_, sitetype1_.site_type as site_typ8_39_1_, variables2_.active as active2_50_2_, variables2_.description as descript3_50_2_, variables2_.id_external_ts_source as id_exter9_50_2_, variables2_.frequency as frequenc4_50_2_, variables2_.name as name5_50_2_, variables2_.popup_display_order as popup_di6_50_2_, variables2_.short_name as short_na7_50_2_, variables2_.id_site as id_site10_50_2_, variables2_.unit_type as unit_typ8_50_2_, variables2_.id_variable_type as id_vari11_50_2_, variables2_.id_site as id_site10_50_0__, variables2_.id_variable as id_varia1_50_0__, parameters3_.name as name2_38_3_, parameters3_.id_site as id_site4_38_3_, parameters3_.value as value3_38_3_, parameters3_.id_site as id_site4_38_1__, parameters3_.id_site_param as id_site_1_38_1__ from site site0_ left outer join site_type sitetype1_ on site0_.id_site_type = sitetype1_.id_site_type left outer join variable variables2_ on site0_.id_site = variables2_.id_site left outer join site_param parameters3_ on site0_.id_site = parameters3_.id_site
同事电脑上同一段JPQL翻译生成的SQL缺失了5个关键ID相关字段,导致查询无法正常执行,同事环境生成的SQL如下:
select site0_.id_site as id_site1_37_0_, sitetype1_.id_site_type as id_site_1_39_1_, variables2_.id_variable as id_varia1_50_2_, parameters3_.id_site_param as id_site_1_38_3_, site0_.active as active2_37_0_, site0_.coord as coord3_37_0_, site0_.name as name4_37_0_, site0_.short_name as short_na5_37_0_, site0_.source as source6_37_0_, sitetype1_.display_name as display_2_39_1_, sitetype1_.marker_default_color as marker_d3_39_1_, sitetype1_.marker_fa_icon as marker_f4_39_1_, sitetype1_.marker_fa_icon_color as marker_f5_39_1_, sitetype1_.marker_fa_icon_prefix as marker_f6_39_1_, sitetype1_.marker_shape as marker_s7_39_1_, sitetype1_.site_type as site_typ8_39_1_, variables2_.active as active2_50_2_, variables2_.description as descript3_50_2_, variables2_.frequency as frequenc4_50_2_, variables2_.name as name5_50_2_, variables2_.popup_display_order as popup_di6_50_2_, variables2_.short_name as short_na7_50_2_, variables2_.unit_type as unit_typ8_50_2_, variables2_.id_site as id_site10_50_0__, variables2_.id_variable as id_varia1_50_0__, parameters3_.name as name2_38_3_, parameters3_.value as value3_38_3_, parameters3_.id_site as id_site4_38_1__, parameters3_.id_site_param as id_site_1_38_1__ from site site0_ left outer join site_type sitetype1_ on site0_.id_site_type = sitetype1_.id_site_type left outer join variable variables2_ on site0_.id_site = variables2_.id_site left outer join site_param parameters3_ on site0_.id_site = parameters3_.id_site
缺失的字段具体为:
site0_.id_site_type as id_site_7_37_0_, variables2_.id_external_ts_source as id_exter9_50_2_, variables2_.id_site as id_site10_50_2_, variables2_.id_variable_type as id_vari11_50_2_, parameters3_.id_site as id_site4_38_3_,
目前已确认双方Spring Boot框架版本完全一致,不确定是否存在配置缺失、依赖差异或其他问题导致ID字段被忽略。
排查方向与解决方案
- 优先清理编译缓存:这类同代码同版本但SQL生成不一致的问题,90%以上是本地编译缓存脏数据导致。直接删除同事本地项目的
target/build编译输出目录,IDEA用户执行File -> Invalidate Caches...勾选清除缓存重启,拉取最新代码后执行全量编译,再验证SQL生成是否正常。同时核对双方实体类代码,确认缺失字段对应的关联注解(@ManyToOne/@OneToMany、@JoinColumn)配置完全一致,没有多余的@Transient注解、异常的insertable/updatable配置。 - 核对全量依赖树:不要只核对Spring Boot版本,执行
mvn dependency:tree(Maven)或gradle dependencies(Gradle)导出双方依赖树对比,重点检查hibernate-core、字节码增强相关依赖(byte-buddy、javassist)、Lombok版本是否一致,排查是否有第三方依赖引入了低版本Hibernate、或者自定义JPA增强插件干扰了实体字段解析。 - 对比本地配置差异:逐行核对双方的
application.yml/application.properties配置,重点检查Hibernate相关配置:是否有自定义的hibernate.integrator_provider、实体拦截器、EntityTuplizer,是否异常开启了字节码增强相关配置,是否存在本地自定义的SQL格式化/拦截逻辑过滤了查询字段。 - 检查IDE配置:确认同事IDE的注解处理器已正常开启,Lombok、JPA相关注解处理器配置与本地一致,IDEA用户检查JPA Facet是否正确识别了所有实体类和关联字段,没有误标记字段为非持久化字段。
- 临时规避方案:如果短时间找不到根因,可以修改JPQL显式声明需要查询的关联ID字段,强制Hibernate在SQL中查询这些字段,绕过自动字段选择的逻辑异常。
内容的提问来源于stack exchange,提问作者Francois
相关产品推荐
相关产品推荐

