JPA匹配ManyToMany关系中的元素子集

时间:2018-06-26 15:33:59

标签: java hibernate jpa

在我的数据库中,我有两个表:Person和Language。这两个表在Hibernate中以多对多关系映射,每个人说多种语言。

现在,我想编写一个方法,该方法接受一种语言列表并返回使用这些语言的所有语言(逻辑与)的人的列表。我试图建立一个像这样的标准:

Restrictions.in("languages", languagesList);

但这会返回一个使用这些语言的任何(逻辑或)语言的人员列表。

我在网上看了一下,发现有一些使用连词和不存在的技巧,但它们看起来更像是黑客,所以我想检查是否有一种更干净的方法来实现这一目标。

有什么建议吗?谢谢。

2 个答案:

答案 0 :(得分:1)

您的问题在于对基础关系模型的理解,而不是Hibernate。 Restrictions.in构建器映射到SQL IN运算符,因此您的结果完全不会出乎意料。

在SQL中,这个问题也很有趣。一种可能的方法是这样(full SQL source):

select u.user_name, count(l.language_name)
  from user u
  join user_language ul on u.user_name = ul.user_name
  join language l on l.language_name = ul.language_name
 where l.language_name in ('spanish', 'italian')
 group by u.user_name
 having count(l.language_name) = 2

查询的参数为:

  • 各种语言('spanish', 'italian'
  • 数组的长度(2

不幸的是,我现在没有Hibernate,但是我认为使用HQL而不是使用Criteria API会更好。

答案 1 :(得分:0)

尝试执行JPQL查询,该查询首先选择所有会说一种语言的人,然后从该列表中选择还会说另一种语言的人。

List<Person> ps = em.createQuery("select distinct p from Person p join p.languages l where l.languageName = 'english' "
+ " and p.id in (select distinct p.id from Person p join p.languages l where l.languageName = 'spanish' )", Person.class).getResultList();

应该工作。