You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 16:35:50