迁移至Hibernate 6后原有JPQL查询报错,o1_0表无FROM子句条目
Hibernate 6升级后JPQL查询报"missing FROM-clause entry"的解决方法
问题根源
看生成的SQL就能定位问题:关联Manufacturer时用到了o1_0.manufacturer_id,但o1_0对应的Item表是在后续才通过join nemo_dev.item o1_0引入的,JOIN顺序完全反了。
Hibernate 6对JPQL的解析和SQL生成逻辑做了调整:在5.6版本中,你通过p.optimizedItem.manufacturer.manufacturerId这种路径关联Manufacturer时,框架会隐式优先处理p.optimizedItem对应的Item表关联;但6.x版本会严格按照你写的显式JOIN顺序执行,导致Manufacturer的JOIN先于Item表的JOIN被处理,此时引用Item表的别名自然就会报"找不到FROM子句条目"的错误。
解决方案
把通过路径关联Manufacturer的写法,改成显式分步JOIN,强制控制JOIN顺序,让Item表先被引入,再关联Manufacturer。
修改后的完整@Query代码:
@Query( "SELECT new Position(p, CASE WHEN p.sourceSetId IS NULL THEN p.sourceSetName ELSE s.name END as sourceSetName, pos.optimizedDisplayOrder) FROM Position p " + "LEFT JOIN Position pos ON pos.projectId = p.projectId AND pos.positionId = p.sourceSetPositionId " + "LEFT JOIN p.optimizedItem oi " // 显式JOIN Item并指定别名 + "LEFT JOIN oi.manufacturer m " // 通过Item别名关联Manufacturer + "LEFT JOIN Set s ON p.sourceSetId = s.setId AND p.projectId = s.projectId " + "WHERE p.setId = :setId AND p.projectId = :projectId " + "AND (UPPER(oi.code) LIKE UPPER(CONCAT('%', :searchParam, '%')) " // 改用Item别名访问字段 + "OR UPPER(m.name) LIKE UPPER(CONCAT('%', :searchParam, '%')) " + "OR UPPER(oi.description) LIKE UPPER(CONCAT('%', :searchParam, '%')))")
关键修改点
- 拆分原有的Manufacturer关联逻辑:先显式JOIN
p.optimizedItem并命名为oi,再通过oi关联Manufacturer - WHERE子句中所有访问
p.optimizedItem的字段,统一改为使用别名oi访问
这样调整后,Hibernate生成的SQL会先引入Item表,再关联Manufacturer表,就能避免找不到表的错误。
内容的提问来源于stack exchange,提问作者CodeWizard1985
相关产品推荐
相关产品推荐

