[英]How to query an M:N relationship with JPA2?
我有一個對象(BlogPost),它包含一個M:N元素集合(標簽)。
如何查詢一個對象(BlogPost),其中至少有一個對象的標簽與一組標簽(由用戶定義)中的元素與JPA2(Hibernate)匹配。
findBlogPostWithAtLeastOneMatchingTag(Collection<Tag> tags){ ???? }
我的主要問題是,我實際上需要比較兩個標簽集合: - BlogPost的標簽集合。 - 我搜索的集合
我嘗試Select p from Post p where p.tags in(:tags)
但它不起作用,因為我的帖子實體只有一個標簽。
那我該怎么做呢?
我的BlogPost實體看起來像這樣。 它有幾個標簽。
@Entity
public class BlogPost{
/** The tags. */
@ManyToMany()
@NotNull
private Set<Tag> tags;
@NotBlank
private String content;
...
}
解決方案不能是JPQL,JPA-Criteria(不是Hibernate-Criteria)也可以。
如果你喜歡JPA Criteria,這就是你的解決方案:
List<Integer> myTagsIds = new ArrayList<Integer> ();
myTagsIds.add(1);
myTagsIds.add(2);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<BlogPost> cq = cb.createQuery(BlogPost.class);
Root<BlogPost> blogPost = cq.from(BlogPost.class);
SetJoin<BlogPost, Tag> tags = blogPost.join(BlogPost_.tags);
Predicate predicate = tags.get(Tag_.id).in(myTagsIds);
cq.distinct(true);
cq.where(predicate);
TypedQuery<BlogPost> tq = em.createQuery(cq);
return tq.getResultList();
此解決方案使用應由JPA實現生成的規范MetaModel類BlogPost_
和Tag_
。
在SQL中它可能是這樣的:
SELECT p FROM Post p WHERE (p.tags INTERSECT :tags IS NOT EMPTY);
然后應用@SqlResultSetMapping
。
您可以使用Criteria API
並按照您的方式啟動,但是對Collection<Tag> 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是當前帖子的ID。 基本上,您選擇的帖子中包含當前帖子標簽中的標簽。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.