【问题标题】:JPA with Eclipselink is ignoring left outer join and add wrong FROM condition带有 Eclipselink 的 JPA 忽略左外连接并添加错误的 FROM 条件
【发布时间】:2020-04-16 08:50:43
【问题描述】:

我有一个具有父菜单的菜单实体:

public class Menu implements Serializable {
   ...
   @JoinColumn(name = "parent" , nullable = true, referencedColumnName = "id")
   @ManyToOne(targetEntity = Menu.class,fetch = FetchType.EAGER, cascade = {}, optional = true)
   //@BatchFetch(BatchFetchType.JOIN)
   @JoinFetch(JoinFetchType.OUTER)
   private Menu parent;
    ...
}

我会创建查询:

SELECT m.*
  FROM menu m LEFT OUTER JOIN menu p ON (p.ID = m.parent)
  WHERE (m.idapp = 1) ORDER BY p.ID ASC NULLS FIRST, m.order ASC

我有一个命名查询:

SELECT m FROM Menu m LEFT OUTER JOIN Menu mp 
WHERE m.applicazione.id = :idapp 
ORDER BY mp.id ASC NULLS FIRST, m.ordine ASC

但结果是:

SELECT ... 
FROM menu t1 LEFT OUTER JOIN menu t0 ON (t0.ID = t1.parent), menu t2 
WHERE (t1.idapp = ?) ORDER BY t2.ID ASC NULLS FIRST, t1.order ASC

这是完全错误的,因为表 t2 创建了一个笛卡尔积。

有什么问题?为什么要添加t2

我还添加了 JoinFetch 注释,但它被忽略了,我现在不知道为什么。

【问题讨论】:

    标签: jpa eclipselink named-query


    【解决方案1】:

    T1 来自您的外部连接关系,SQL 显示它被正确地用于引入与您的查询正在选择的菜单实例关联的所有父实例。

    具有 t2 的笛卡尔积是您使用查询“SELECT m FROM Menu m LEFT OUTER JOIN Menu mp”定义的。查询应该是:

    SELECT m FROM Menu m WHERE m.applicazione.id = :idapp ORDER BY m.ordine ASC
    

    如果您必须使用父关系进行排序,则格式为:

    SELECT m FROM Menu m LEFT OUTER JOIN m.parent mp WHERE m.applicazione.id = :idapp 
    ORDER BY mp.id ASC NULLS FIRST, m.ordine ASC
    

    请注意,尽管 SQL 可能有一个额外的表连接,因为行为是提供者和映射特定的 - 提取连接不能用于过滤,因为它会扭曲返回对象的结果。

    SELECT m FROM Menu m WHERE m.applicazione.id = :idapp 
    ORDER BY m.parent ASC NULLS FIRST, m.ordine ASC
    

    也可以在 EclipseLink 中工作,因为它在 Menue 中有 fk 可以使用,而无需触发连接,但不是必需的。

    【讨论】:

    • 是的,我忘记了 mp 已加入其父表,所以 T2。我使用了最后一个查询。我所做的另一个更改是删除 @JoinFetch 并使用 @BatchFetch(JOIN)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2012-05-04
    相关资源
    最近更新 更多