HQL检查对象是否包含所请求集的所有元素

时间:2016-02-13 09:39:05

标签: java spring jpa hql spring-data-jpa

我有两个实体。例如,帖子和标签。 我必须编写一个方法,该方法仅包含查询中提到的所有标记的帖子。

我试过

@Query("select distinct p from posts p join p.tags t where t in ?1")
Page<Post> findDistinctByTagsIn(Set<Tag> tagSet, Pageable pageable);

然而,如果tagSet中包含至少一个标签,则需要发布。

如何仅使用HQL和JPA存储库解决此问题?

UPD:

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "posts_tags", joinColumns = {
        @JoinColumn(name = "post_id", nullable = false, updatable = false)},
        inverseJoinColumns = {@JoinColumn(name = "tag_id")})
public Set<Tag> getTags() {
    return tags;
}

1 个答案:

答案 0 :(得分:2)

添加到Tag课程下一个ManyToOne关系:

@Entity
public class Tag{
    ...

    private Post post;

    @ManyToOne
    @JoinTable(name = "posts_tags",
            joinColumns = {@JoinColumn(name = "tag_id")},
            inverseJoinColumns = {@JoinColumn(name = "post_id")})
    public Post getPost(){
        return post;
    }

    ...
}

让我们尝试构建查询。

我们不需要包含标签列表之外的标签的帖子。我们将使用下一个查询选择它们:

select t.post from Tag t where t not in (:tagSet) and t.post is not null

我们不需要没有任何标签的帖子。我们也选择它们:

select p from Post p where p.tags is empty

现在让我们一起加入我们的问题:

select p from Post p where 
p not in (select t.post from Tag t where t not in (:tagSet) and t.post is not null) 
and p not in (select p2 from Post p2 where p2.tags is empty)

您可以使用命名参数绑定此查询:

Page<Post> findDistinctByTagsIn(@Param("tagSet") Set<Tag> tagSet, Pageable pageable);