title: Query from combined spring data specification has multiple joins on same table
body: <p>Sorry if my terminology isn't correct.</p>
  
  <p>We are using spring data, JpaRepositories and criteria queries as our method to query data from our database.</p>
  
  <p>I have a problem that when I combine two specifications such as I do with hasTimeZone and hasCity in hasCityAndTimeZone in the code example below it does a join on the same table twice, so the query below will look something like </p>
  
  <pre><code>select * from Staff, Location, Location
  </code></pre>
  
  <p>Is there any way to have the two specifications use the same join instead of each defining their own join that is essentially the same?</p>
  
  <p>Sorry the code probably isn't complete I was just trying to show a quick example.</p>
  
  <pre><code>class Staff {
      private Integer id;
      private Location location;
  }
  
  class Location {
      private Integer id; 
      private Integer timeZone;
      private Integer city;
  }
  
  class StaffSpecs {
      public static Specification&lt;Staff&gt; hasTimeZone(Integer timeZone) {
          return new Specification&lt;Staff&gt;() {
              @Override
              public Predicate toPredicate(Root&lt;Staff&gt; root, CriteriaQuery&lt;?&gt; query, CriteriaBuilder cb) {
                  Path&lt;Integer&gt; timeZonePath = root.join(Staff_.location).get(Location_.timeZone);
                  return cb.equal(timeZonePath, timeZone);
              }
          }
      }
  
      public static Specification&lt;Staff&gt; hasCity(Integer city) {
          return new Specification&lt;Staff&gt;() {
              @Override
              public Predicate toPredicate(Root&lt;Staff&gt; root, CriteriaQuery&lt;?&gt; query, CriteriaBuilder cb) {
                  Path&lt;Integer&gt; cityPath = root.join(Staff_.location).get(Location_.city);
                  return cb.equal(cityPath, city);
              }
          }
      }
  
      public static Specification&lt;Staff&gt; hasCityAndTimeZone(Integer city, Integer timeZone) {
          return where(hasCity(city)).and(hasTimeZone(timeZone));
      }
  }
  </code></pre>