title: JPA: Find all articles that have a common set of tags
body: <p>I have the following entities:</p>
  
  <pre><code>@Entity
  public class Article{
      @Id
      private String id;
  
      @ManyToMany(cascade = CascadeType.PERSIST)
      private Set&lt;Tag&gt; tags;
  
  //non-relevant code
  }
  
  @Entity 
  public class Tag{
      @Id
      private String id;
  
      @Basic
      @Column(nullable = false, unique = true, length = 32)
      private String name;
  
  //non-relevant code
  }
  </code></pre>
  
  <p>How can I efficiently find all <code>Article</code> entities that have a common <code>set</code> of tags?</p>
  
  <p>The naive approach is to find all the articles that belong to each <code>tag</code> and then return the <code>intersection</code> of all the article sets. Something like:</p>
  
  <pre><code>public Set&lt;Article&gt; findByTags(Set&lt;Tag&gt; tags){
      Set&lt;Article&gt; result = new HashSet&lt;&gt;();
  
      if(tags.isEmpty()){
          return result;
      }
  
      Iterator&lt;Tag&gt; i = tags.iterator();
      result.addAll(i.next().getArticles());
  
      while(i.hasNext() &amp;&amp; !result.isEmpty()){
          result.retainAll(i.next());
      }
  
      return result;
  }
  </code></pre>
  
  <p>My question is "<strong><em>Is there more efficient way of doing this, that does not require to fetch possibly all the articles from the DB, like this one ?</em></strong> Maybe through a JPQL query or using the <code>CriteriaBuilder</code> (I've never used it before)"</p>