当有 order by 子句时,openJPA 外连接可选多对一
Posted
技术标签:
【中文标题】当有 order by 子句时,openJPA 外连接可选多对一【英文标题】:openJPA outer join on optional many-to-one when have order by clause 【发布时间】:2013-11-07 20:21:31 【问题描述】:我有一个场景,我希望生成的 SQL 始终使用外部联接作为可选的 ManyToOne。 我正在使用 OpenJPA 2.2.1.x。
两个实体:Event 和 Rule,Event 与 Rule 有一个可选的 ManyToOne 单向关系。以下是两个实体类:
@Entity
public class Event
@Id
private String uuid;
private Date eventTime;
@ManyToOne(optional=true)
private Rule rule;
@Entity
public class Rule
@Id
private String uuid;
private int rowNum;
如果在 JPQL 中我对事件属性(例如,事件时间)使用 ORDER BY,它会在事件和规则表之间生成 LEFT OUTER JOIN。 JPQL:
SELECT e from Event e order by e.eventTime desc
SQL:
SELECT t0.uuid, t0.eventTime, t1.uuid, t1.rowNum FROM Event t0 LEFT OUTER JOIN Rule t1 ON t0.RULE_UUID = t1.uuid ORDER BY t0.eventTime DESC
如果在 JPQL 中我在 Rule 属性(例如 rowNum)上使用 ORDER BY,它会在事件和规则表之间生成 INNER JOIN。 JPQL:
SELECT e from Event e order by order by e.rule.rowNum asc
SQL:
SELECT t0.uuid, t0.eventTime, t1.uuid, t1.rowNum FROM Event t0 INNER JOIN Rule t1 ON t0.RULE_UUID = t1.uuid ORDER BY t1.rowNum ASC
我的问题是:
-
这是基于不同ORDER BY 子句生成两种不同类型的JOIN 的正确行为吗?
除了使用原生 SQL 之外,还有什么方法可以让 openJPA 始终生成 OUTER JOIN? (我尝试了 LEFT OUTER JOIN FETCH,它没有帮助:-()。
提前致谢,
刘大卫
【问题讨论】:
【参考方案1】:使用 LEFT JOIN 可以达到目的。
SELECT e FROM Event e LEFT JOIN e.rule r ORDER BY r.rowNum ASC
这将生成以下 SQL:
SELECT t0.uuid, t0.eventTime, t2.uuid, t2.rowNum, t1.rowNum FROM Event t0 LEFT OUTER JOIN Rule t1 ON t0.RULE_UUID = t1.uuid LEFT OUTER JOIN Rule t2 ON t0.RULE_UUID = t2.uuid ORDER BY t1.rowNum ASC
JPQL中有一点需要注意:ORDER BY必须作用于r.rowNum而不是e.rule.rowNum,否则会产生INNER JOIN。
您可能已经注意到生成的 SQL 在 RULE 表上有两个 OUTER JOIN。
【讨论】:
以上是关于当有 order by 子句时,openJPA 外连接可选多对一的主要内容,如果未能解决你的问题,请参考以下文章
OpenJPA/MySQL:在 where 子句中使用同一张表时修改表
OleDbException:ORDER BY 子句中的语法错误