【问题标题】:Left Join an Element collection using JPQL使用 JPQL 左连接元素集合
【发布时间】:2019-07-12 13:05:00
【问题描述】:

假设我有这些类,请注意实体无论如何都不相关。

@Entity
class Laptop {
 @Id
 String userId;
 @Column
 String name;
 ...
}

@Entity
class Foo {
 ...

 @Column
 @ElementCollection
 List<String> idsPointingToAnEntity;

 ...
}

鉴于我有这个具有idsPointingToAnEntity 属性的Foo 类,我可以在那里存储笔记本电脑ID 列表或任何字符串ID。假设Foo 有 idsPointingToAnEntity=[1,2,3],这个 [1,2,3] 在数据库中有一个等效的笔记本电脑条目。

如果结果是按笔记本电脑名称排序的 Foo 列表,我如何才能在 JPQL 中通过排序离开加入/加入它们。

理论上我认为是这样的。

Select f From Foo f LEFT JOIN Laptop l ON l.id IN f.idsPoitingToAnEntity ORDER by l.name

但这对我来说有一个错误,因为f.idsPoitingToAnEntity 是一个联接表。

注意:idsPointingToAnEntity 也可以是另一个实体,使List&lt;Laptop&gt; 不是一个选项

【问题讨论】:

  • 你不能在idsPointingToAnEntity 上使用@OrderColumn 吗?目标表包含列name,因此@OrderColumn(name = "name") 应该与@ElementCollection 一起使用...示例here,检查标题“添加 OrderColumn”
  • @OrderColumn 不起作用,因为它没有绑定到名称,它可以是任何实体的属性

标签: jpa jpql


【解决方案1】:

你可以使用 no Joins 来获得这个结果:

SELECT l FROM Laptop l, Foo f
WHERE l.id IN f.idsPointingToAnEntity ORDER BY l.name

或者使用CROSS JOIN,一种不需要任何匹配条件的特殊连接:

SELECT l FROM Laptop l
CROSS JOIN Foo f
WHERE l.id IN f.idsPointingToAnEntity ORDER BY l.name

PS:在这种情况下使用交叉连接的问题是它生成笛卡尔积,而不是左侧的所有行。

【讨论】:

    【解决方案2】:

    如果您使用 JPA 2.1 或更高版本,您可以在 JPQL 中对不相关的实体使用 JOIN ON。首先加入 IDs 表,如下所示:

    select f from Foo f 
    join f.idsPointingToAnEntity id 
    join Laptop l ON id=l.id
    join AnotherEntity a ON id=a.id
    

    【讨论】:

      【解决方案3】:

      这里的简短回答就是不要那样做。它滥用了特定功能,并且随着列表的增长可能会导致麻烦。你没有很好的理由这样做。如果您认为列表很小,那么数据库负载很小,没有理由将引用放入ElementCollection。如果列表变大,您肯定不想要ElementCollection。

      参考Difference between @OneToMany and @ElementCollection?。 ElementCollection 用于在Foo 和idsPointingToAnEntity 之间创建OneToMany。它绝对不能用作One-To-Many Relationship with Join Table。

      【讨论】:

        猜你喜欢
        • 2015-05-23
        • 2015-03-04
        • 2020-05-10
        • 2015-07-18
        • 2012-10-31
        • 1970-01-01
        • 2015-04-21
        • 1970-01-01
        • 2012-06-23
        相关资源
        最近更新 更多