JpaSpecificationExecutor搭配@EntityGraph多条件查询报错问题咨询
问题根因
你在两个独立的Specification条件中分别对promoProGesCodeLer关联创建了两次独立的LEFT JOIN,而@EntityGraph本身会为该关联生成FETCH JOIN。Hibernate 5.4.15版本处理这类重复关联join时存在缺陷,会导致FETCH JOIN对应的关联所有者和查询生成的重复别名匹配失败,最终抛出"query specified join fetching, but the owner of the fetched association was not present in the select list"异常。
解决方案
方案1:复用关联Join实例(推荐,改动最小)
将多个条件的关联Join逻辑合并,复用同一个promoProGesCodeLer的Join实例,避免生成重复的关联别名,修改后的Specification代码如下:
protected Specification<TrazabilidadContenedor> createSpecification(TrazabilidadContenedorCriteria criteria) { Specification<TrazabilidadContenedor> specification = Specification.where(null); if (criteria == null) { return specification; } return specification.and((root, query, builder) -> { // 全局复用promoProGesCodeLer的Join实例,避免重复创建 Join<TrazabilidadContenedor, PromoProGesCodLer> promoProGesCodeLerJoin = root.join( TrazabilidadContenedor_.promoProGesCodeLer, JoinType.LEFT ); Predicate predicate = builder.conjunction(); // 处理promocionId查询条件 if (criteria.getPromocionId() != null) { Join<PromoProGesCodLer, Promocion> promocionJoin = promoProGesCodeLerJoin.join( PromoProGesCodLer_.promocion, JoinType.LEFT ); predicate = builder.and( predicate, builder.equal(promocionJoin.get(Promocion_.id), criteria.getPromocionId()) ); } // 处理gestoraId查询条件 if (criteria.getGestoraId() != null) { Join<PromoProGesCodLer, ProGesCodLer> proGesCodLerJoin = promoProGesCodeLerJoin.join( PromoProGesCodLer_.procesoGestoraCodLer, JoinType.LEFT ); Join<ProGesCodLer, ProcesoGestora> procesoGestoraJoin = proGesCodLerJoin.join( ProGesCodLer_.procesoGestora, JoinType.LEFT ); Join<ProcesoGestora, Gestora> gestoraJoin = procesoGestoraJoin.join( ProcesoGestora_.gestora, JoinType.LEFT ); predicate = builder.and( predicate, builder.equal(gestoraJoin.get(Gestora_.id), criteria.getGestoraId()) ); } return predicate; }); }
同时你当前@EntityGraph的attributePaths中存在重复配置项promoProGesCodeLer.procesoGestoraCodLer.procesoGestora,建议删除重复项减少不必要的关联查询。
方案2:手动在Specification中声明FETCH JOIN
如果需要更灵活控制关联加载逻辑,可以放弃@EntityGraph注解,改为在Specification中手动通过fetch方法声明需要加载的关联,完全由代码控制关联逻辑,避免和注解自动生成的FETCH JOIN冲突。
方案3:升级框架版本
该问题属于Hibernate 5.4早期版本的已知bug,你可以选择升级版本修复:
- Hibernate版本升级到5.4.30.Final及以上,或5.5.x系列稳定版
- 对应的Spring Boot版本可以升级到2.4.x及以上版本,升级后需要做好兼容性测试。
内容的提问来源于stack exchange,提问作者asax_ack
相关产品推荐
相关产品推荐

