如何查询与JPA2的M:N关系?

我有一个对象(BlogPost),它包含一个M:N元素集合(标签)。

如何查询一个对象(BlogPost),其中至少有一个对象与一组标签(由用户定义)中的元素与JPA2(Hibernate)匹配。

findBlogPostWithAtLeastOneMatchingTag(Collection tags){ ???? } 

我的主要问题是,我实际上需要比较两个标签集合: – BlogPost的标签集合。 – 我搜索的collections品

我尝试Select p from Post p where p.tags in(:tags)但它不起作用,因为我的post实体只有一个标签。

那我该怎么做呢?

我的BlogPost实体看起来像这样。 它有几个标签。

 @Entity public class BlogPost{ /** The tags. */ @ManyToMany() @NotNull private Set tags; @NotBlank private String content; ... } 

解决方案不能是JPQL,JPA-Criteria(不是Hibernate-Criteria)也可以。

如果你喜欢JPA Criteria,这就是你的解决方案:

 List myTagsIds = new ArrayList (); myTagsIds.add(1); myTagsIds.add(2); CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(BlogPost.class); Root blogPost = cq.from(BlogPost.class); SetJoin tags = blogPost.join(BlogPost_.tags); Predicate predicate = tags.get(Tag_.id).in(myTagsIds); cq.distinct(true); cq.where(predicate); TypedQuery tq = em.createQuery(cq); return tq.getResultList(); 

此解决方案使用应由JPA实现生成的规范MetaModel类BlogPost_Tag_

方法1:

在SQL中它可能是这样的:

 SELECT p FROM Post p WHERE (p.tags INTERSECT :tags IS NOT EMPTY); 

然后应用@SqlResultSetMapping

方法2:

您可以使用Criteria API并按照您的方式启动,但对Collection tags进行循环:

 * make a union of single query results from `Select p from Post p where p.tags in(:tags)`; * take distinct over result of union. 

查询将是服务器端的,您不必在Java中进行脏工作。

你可以做点什么

从Post t中选择t,其中t.tag in(从post p中选择p.tag,其中p.id =:id)

id是当前post的ID。 基本上,您正在选择包含当前post标签中的标签的post。