0

我有一个场景,我希望生成的 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 中我对事件属性(例如 eventTime)使用 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 

我的问题是:

  1. 这是基于不同的 ORDER BY 子句生成两种不同类型的 JOIN 的正确行为吗?
  2. 除了使用原生 SQL 之外,有什么方法可以让 openJPA 始终生成 OUTER JOIN?(我尝试了 LEFT OUTER JOIN FETCH,它没有帮助:-()。

提前致谢,

刘大卫

4

1 回答 1

0

使用 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。

于 2013-11-09T03:48:12.120 回答