当有 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 外连接可选多对一的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ORDER BY 子句中的绑定参数不对结果进行排序?

OpenJPA/MySQL:在 where 子句中使用同一张表时修改表

ORDER BY 子句是不是会减慢查询速度?

OleDbException:ORDER BY 子句中的语法错误

使用具有不同 order by 子句的 postgres 窗口函数

SQL Server 2000:在 order by 子句中选择大小写