带有 Eclipselink 的 JPA 忽略左外连接并添加错误的 FROM 条件
JPA with Eclipselink is ignoring left outer join and add wrong FROM condition
我有一个具有父菜单的菜单实体:
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
这是完全错误的,因为 table t2 创建了一个笛卡儿积。
问题是什么?为什么要添加t2?
我还添加了 JoinFetch 注释,但它被忽略了,我现在不知道为什么。
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 可能有一个额外的 table 连接,因为行为是特定于提供者和映射的 - 提取连接不用于过滤,因为它会扭曲结果返回对象。
SELECT m FROM Menu m WHERE m.applicazione.id = :idapp
ORDER BY m.parent ASC NULLS FIRST, m.ordine ASC
也可能在 EclipseLink 中工作,因为它在 Menue 中有 fk 可以使用而无需触发连接,但不是必需的。
我有一个具有父菜单的菜单实体:
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
这是完全错误的,因为 table t2 创建了一个笛卡儿积。
问题是什么?为什么要添加t2?
我还添加了 JoinFetch 注释,但它被忽略了,我现在不知道为什么。
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 可能有一个额外的 table 连接,因为行为是特定于提供者和映射的 - 提取连接不用于过滤,因为它会扭曲结果返回对象。
SELECT m FROM Menu m WHERE m.applicazione.id = :idapp
ORDER BY m.parent ASC NULLS FIRST, m.ordine ASC
也可能在 EclipseLink 中工作,因为它在 Menue 中有 fk 可以使用而无需触发连接,但不是必需的。