How to query an M:N relationship with JPA2?

时光总嘲笑我的痴心妄想 提交于 2019-11-27 21:40:42

If you like JPA Criteria, this is the solution for you:

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();

This solution makes use of the canonical MetaModel classes BlogPost_ and Tag_ that should be generated by your JPA implementation.

Approach 1:

In SQL it could be something like:

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

Then apply the @SqlResultSetMapping.

Approach 2:

You can use Criteria API and start as you did but make a loop over Collection<Tag> tags as:

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

Query will be server-side and you wouldn't have to do dirty work in Java.

You could do something like

Select t from Post t where t.tag in (select p.tag from Post p where p.id=:id)

id is the id of the current post. Basically you are selecting post with tags that are in the tags of current post.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!