如何将LEFT JOIN和Where子句与JPQL结合使用?

Mik*_*378 12 java hibernate jpa left-join

我有两个JPA实体:

  • 时间表(包含预订清单)
  • 预订(包含日期字段:日期resDate)

我的目标是只检索与日期参数(planningDate)匹配的预订,同时检索所有日程表,无论预定是否存在于此给定日期.

所以我写道:

SELECT s FROM Schedule as s LEFT JOIN s.reservations as r WHERE r.resDate = :planningDate order by s.startHour
Run Code Online (Sandbox Code Playgroud)

尽管我的LEFT JOIN,为什么没有在这个日期没有预订的时间表?

可能与本机查询一样,LEFT JOIN在与WHERE子句组合时看起来像INNER JOIN.

那么,如何更改查询以满足我的要求?我没有在JPQL中找到特定功能.

Cha*_*aos 15

啊,这确实是JPA的经典之作.以下的答案我提供了-我无法解释究竟为什么它的工作原理,但我可以解决这个你

简短的回答,试试:

SELECT s FROM Schedule as s LEFT JOIN s.reservations as r WHERE 
(r.resDate is null or r.resDate = :planningDate) order by s.startHour
Run Code Online (Sandbox Code Playgroud)

(这里的关键是"r.resDate为null"部分)

答案:明确表示这不是由hibernate/JPA人员工作的,但确实如此.生成的SQL也非常有效.如果有人能解释为什么会这样,我会留下最深刻的印象.我多年前就学会了这种模式,但不能为我的生活记住哪里.

一注:有一个情况下,这将无法工作,这是在目前还没有预订此调度的实例.在这种情况下,我能提供的唯一答案是你可以将你的查询包装在try/catch中以获取"NoResultException",并在没有where子句的情况下再次查询(显然,如果没有预留,则没有对resDate的保留planningDate)

  • 这只有在`resDate`为非NULL列时才有效.如果它可以为空,那么你可能会得到错误的结果.您可以使用特定于Hibernate的`WITH`,例如`LEFT JOIN s.reservations r WITH r.resDate =:planningDate`,这将生成带有JOIN中附加子句的正确SQL语句,例如`from t_schedule s左边连接t_reservations r on r.schedule_id = s.id和r.resDate ='some date'`. (3认同)