JPA无双向关联时左连接查询报错,能否按现有方式执行?
问题解决:JPA左连接报错"Path expected for join!"
你遇到的Path expected for join!错误,是因为当前JPQL的左连接写法不符合JPA规范——由于ShipyardModel实体未声明与Boat的双向关联,直接使用left join Boat b on b.shipyardModel = sm的写法在部分JPA版本(尤其是2.0及以下)中不被支持,或者语法存在问题。
以下是两种可行的解决方案:
方案一:用子查询统计Boat数量(兼容性更好)
通过子查询替代左连接来获取每个ShipyardModel对应的Boat计数,无需依赖实体间的双向关联,写法如下:
@Query(" SELECT new br.com.easymarine.dto.ShipyardModelDTO" + "(sm.id, sm.name, sm.commercialLength, sm.length, sm.width, sm.height, sm.beam, sm.weightWithoutMotor, sm.weightWithMotor, sm.modelYear, sm.shipType, s.id, s.name," + "(SELECT COUNT(b.id) FROM Boat b WHERE b.shipyardModel = sm)) " + "FROM ShipyardModel sm " + "JOIN sm.shipyard s") List<ShipyardModelDTO> findAllShipyardModelDTO();
方案二:调整左连接语法(需JPA 2.1+支持)
如果项目使用JPA 2.1及以上版本,可以保留左连接,但必须修正GROUP BY子句(需包含所有SELECT中的非聚合字段),同时确保连接条件语法正确:
@Query(" SELECT new br.com.easymarine.dto.ShipyardModelDTO" + "(sm.id, sm.name, sm.commercialLength, sm.length, sm.width, sm.height, sm.beam, sm.weightWithoutMotor, sm.weightWithMotor, sm.modelYear, sm.shipType, s.id, s.name, COUNT(b.id)) " + "FROM ShipyardModel sm " + "JOIN sm.shipyard s " + "LEFT JOIN Boat b ON b.shipyardModel.id = sm.id " + "GROUP BY sm.id, sm.name, sm.commercialLength, sm.length, sm.width, sm.height, sm.beam, sm.weightWithoutMotor, sm.weightWithMotor, sm.modelYear, sm.shipType, s.id, s.name") List<ShipyardModelDTO> findAllShipyardModelDTO();
注意:方案二中的GROUP BY必须覆盖所有SELECT里未被聚合的字段,否则会触发SQL语法错误,这是数据库分组查询的硬性要求。
内容的提问来源于stack exchange,提问作者rafaelpadu
相关产品推荐
相关产品推荐

