title: JPA Specifications by Example
body: <p>Spring Boot here. I'm trying to wrap my head around <code>JpaRepositories</code> and <code>Specifications</code> when used in the context of implementing complex queries and am struggling to see the "forest through the trees" on several items.</p>
  
  <p>A canonical example of a <code>Specification</code> is as follows:</p>
  
  <pre><code>public class PersonSpecification implements Specification&lt;Person&gt; {
      private Person filter;
  
      public PersonSpecification(Person filter) {
          super();
          this.filter = filter;
      }
  
      public Predicate toPredicate(Root&lt;Person&gt; root, CriteriaQuery&lt;?&gt; cq,
              CriteriaBuilder cb) {
          Predicate p = cb.disjunction();
  
          if (filter.getName() != null) {
              p.getExpressions()
                      .add(cb.equal(root.get("name"), filter.getName()));
          }
  
          if (filter.getSurname() != null &amp;&amp; filter.getAge() != null) {
              p.getExpressions().add(
                      cb.and(cb.equal(root.get("surname"), filter.getSurname()),
                              cb.equal(root.get("age"), filter.getAge())));
          }
  
          return p;
      }
  }
  </code></pre>
  
  <p>In this <code>toPredicate(...)</code> method, what do the <code>Root&lt;Person&gt;</code> and <code>CriteriaQuery</code> represent? Most importantly, it <em>sounds</em> like you need to create one <code>Specification</code> impl for <em>each</em> type of filter you want to apply, because each spec gets translated into one and only one predicate...so for instance if I wanted to find all people with a surname of "Smeeb" and an age greater than 25, it sounds like I would need to write a <code>LastnameMatchingSpecification&lt;Person&gt;</code> as well as a <code>AgeGreaterThanSpecification&lt;Person&gt;</code>. Can someone confirm or clarify this for me?!</p>