Spring+Hibernate:如何用JPQL查询含未删除Ramps的Window(无则返回空列表)
用JPQL实现符合需求的Window查询
原查询的问题分析
你之前的查询在WHERE中添加r.isDeleted = false,会导致没有关联Ramps的Window被过滤掉——因为此时r为null,null = false不成立,不符合WHERE条件。同时,这种写法也无法处理“Window的Ramps全为已删除”的场景,会直接过滤掉这类Window。
正确的JPQL写法
要实现你的需求(返回所有Window,仅保留未删除的Ramps;无有效Ramps时返回空列表),可以使用LEFT JOIN WITH(关联阶段过滤Ramps),结合FETCH JOIN或EntityGraph来加载关联数据:
方式1:使用LEFT FETCH JOIN WITH(查询级加载关联)
@Query(""" SELECT w FROM Window w LEFT FETCH JOIN w.ramps r WITH r.isDeleted = false WHERE w.id = :id """) Optional<Window> findByIdWithNotDeletedRamps(long id);
如果要查询所有Window,去掉WHERE条件即可:
@Query(""" SELECT w FROM Window w LEFT FETCH JOIN w.ramps r WITH r.isDeleted = false """) List<Window> findAllWithNotDeletedRamps();
方式2:结合EntityGraph与LEFT JOIN WITH
如果你习惯用EntityGraph控制关联加载,可以保留EntityGraph,同时用LEFT JOIN WITH过滤Ramps:
@Query(""" SELECT w FROM Window w LEFT JOIN w.ramps r WITH r.isDeleted = false WHERE w.id = :id """) @EntityGraph(attributePaths = {"warehouse", "ramps"}) Optional<Window> findByIdWithNotDeletedRamps(long id);
效果验证
这两种写法都能覆盖你需要的所有场景:
- Window存在未删除的Ramps:返回Window,
ramps列表仅包含未删除的记录 - Window的Ramps全为已删除:返回Window,
ramps列表为空 - Window无任何Ramps:返回Window,
ramps列表为空
核心原理
LEFT JOIN WITH是在关联Ramps的阶段就过滤掉已删除的记录,而不是在WHERE阶段过滤整个Window。这样既保证了所有Window都能被查询到,又能自动过滤掉无效的Ramps关联。
内容的提问来源于stack exchange,提问作者Matexon
相关产品推荐
相关产品推荐

