JPQL 查询:属于多个类别的项目

Posted

技术标签:

【中文标题】JPQL 查询:属于多个类别的项目【英文标题】:JPQL query: Item that belongs to multiple categories 【发布时间】:2020-01-30 19:18:26 【问题描述】:

有一个实体 Items 有一个名为 categories 的集合字段,我需要找到至少属于两个特定类别的项目,但我找不到方法构建正确的 JPQL 查询。

@Entity
public class Items 
@ManyToMany (fetch = FetchType.EAGER)
private List<Category> categories;

我可以找到具有一个类别的项目:

SELECT i FROM Item i WHERE :cat MEMBER OF item.categories

我可以选择多个类别中的任何一个:

SELECT i FROM Item i WHERE :cat1 MEMBER OF item.categories OR :cat MEMBER OF item.categories

但是当我尝试选择至少有两个特定类别的项目时,以下查询没有得到任何项目:

SELECT i FROM Item i WHERE :cat1 MEMBER OF item.categories AND :cat2 MEMBER OF item.categories

这样做的正确方法是什么?

最好的问候, 巴勃罗。

【问题讨论】:

您是否有具有项目到类别关系的实体? 我的意思是 ItemsCategories 实体 是的,Category实体与Item实体有ManyToMany关系:@ManyToMany (fetch = FetchType.EAGER) private List categories; 【参考方案1】:

这个问题发生在我的 ObjectDB 身上。 我也联系过他们,答案是这样的:

这似乎是JPQL查询如何转换成SQL的结果 像执行前的语法。 MEMBER OF 是使用 JOIN 实现的 用于迭代集合的新合成变量。在你的 查询 item.categories 出现两次,但相同的合成变量 对该集合的迭代用于这两种情况,并且 变量不能用相同的值匹配 AND 的两边。

我们可能不得不对每个 MEMBER OF 使用单独的迭代作为 您的帖子所展示的结果似乎是不可接受的(尽管 JQPL 由于转换,它本身在某些已知情况下具有奇怪的行为 加入)。但是,使用单独的变量有时可能会使 不必要地查询更复杂和缓慢(例如,对于 OR 查询 您的帖子),因此任何更改都需要仔细规划。

作为一个快速的解决方案,您可以用 2 显式替换 AND 的 MEMBER OF 用 2 个独立的 JOIN 变量对集合进行迭代 变量。

因此,解决方案是使用以下查询:

SELECT DISTINCT item
FROM Item item JOIN item.categories cat1 JOIN item.categories cat2
WHERE cat1 = :cat1 AND cat2 = :cat2

我不知道这是否仅适用于这个特定的 JPA 实现 (ObjectDB)。 无论如何,如果有人有类似的问题,我希望这篇文章可以帮助。

【讨论】:

以上是关于JPQL 查询:属于多个类别的项目的主要内容,如果未能解决你的问题,请参考以下文章

通过一个 SQL 查询从多个类别中检索最常见的项目名称及其最高价格

MySQL 选择查询与连接和大量的结果优化

jpql语句

如何使用 JPQL 删除 ManyToMany 项目?

查找最佳类别匹配的 SQL 查询

在 JPQL 查询中检查集合上的 NULL 吗?