【问题标题】:Finding items with a set containing all elements of a given set with jpql使用 jpql 查找包含给定集合的所有元素的集合的项目
【发布时间】:2021-10-26 06:06:45
【问题描述】:

我想在它们的标签集中找到包含 所有 给定标签的项目。

以下是简化的类:

@Entity   
class Item {
  @ManyToMany
  var tags: java.util.Set[Tag] = new java.util.HashSet[Tag]()
}

@Entity
class Tag {
  @ManyToMany(mappedBy="tags")
  var items: java.util.Set[Item] = new java.util.HashSet[Item]
}

如果我这样尝试

select distinct i 
from Item i join i.tags t
where t in (:tags)

我得到了包含 any 的给定标签的项目。这并不奇怪,但我想要包含 all 给定标签的项目。所以我换个方式试试:

select distinct i 
from Item i join i.tags t
where (:tags) in t

我收到错误消息org.hibernate.exception.SQLGrammarException: arguments of row IN must all be row expressions。如果tags 只包含一个标签,它就可以工作,但它会失败并不止于此。

如何在 JPQL 中表达这一点?

【问题讨论】:

  • 因为我认为你无法将 set 与休眠中的其他数组进行比较。我认为你必须重写你的 sql 查询代码。
  • Query query = session.createQuery("from Stock where stockId in (:code)"); query.setParameterList("code", idList);
  • 感谢您在问题中展示了如何获取包含任何给定标签的项目!这就是我一直在寻找的。我可以确认它也适用于 @ElementCollections。

标签: java sql hibernate jpa jpql


【解决方案1】:

诀窍是使用计数:

select i from Item i join i.tags t
where t in :tags group by i.id having count(i.id) = :tagCount

【讨论】:

  • 这是让你永远看到它的那些东西之一,然后当你看到它时,你无法相信你一直没有看到它
【解决方案2】:

我刚遇到和你一样的问题。我使用了荒谬的归约法:

select distinct i from Item i where i not in (select i2 from Item i2 join i2.tags t where t not in :tags) 

【讨论】:

  • 我喜欢这种方法,因为我已经有一个查询返回了我不想要的内容,但是我需要向内部选择添加几个条件才能保留子查询结果小的。相反,我使用stackoverflow.com/a/21645545/429896 此处描述的计数方法,不需要在“分组依据”之后添加内容。
  • Item 包含没有任何标签的元素时,这对我来说失败了。
  • 这不匹配所有给定的 - 但只匹配单个。如果不在 - 而不是“不在所有”中,则子选择将匹配。您只是将最初的问题覆盖到了 2 中,没有解决它。
  • 这相当于“从项目 i 中选择不同的 i where i in (..tags)”,因此不只匹配包含所有给定标签的那些。
猜你喜欢
  • 2012-10-31
  • 2018-06-18
  • 2023-03-18
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
相关资源
最近更新 更多