title: How to use projections and specifications with spring data jpa?
body: <p>I'm not able to use Spring Data JPA projections and specifications together. I have the following setup:</p>
  
  <p><strong>Entity:</strong></p>
  
  <pre><code>@Entity
  public class Country {
  
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
  
      @Column(name = "NAME", nullable = false)
      private String name;
  
      @Column(name = "CODE", nullable = false)
      private String code;
  
      ---getters &amp; setters---
  
  }
  </code></pre>
  
  <p><strong>Projection Interface:</strong> </p>
  
  <pre><code>public interface CountryProjection {
      String getName();
  }
  </code></pre>
  
  <p><strong>Country Specification:</strong> </p>
  
  <pre><code>public class CountrySpecification {
      public static Specification&lt;Country&gt; predicateName(final String name) {
          return new Specification&lt;Country&gt;() {
              @Override
              public Predicate toPredicate(Root&lt;Country&gt; eventRoot, CriteriaQuery&lt;?&gt; criteriaQuery, CriteriaBuilder criteriaBuilder) {
                  return criteriaBuilder.equal(eventRoot.get(Country_.name), name);
              }
          };
      }
  }
  </code></pre>
  
  <p><strong>Repository:</strong> </p>
  
  <pre><code>public interface CountryRepository extends JpaRepository&lt;Country, Long&gt;, JpaSpecificationExecutor&lt;Country&gt; {
      List&lt;CountryProjection&gt; findByName(String name); // works fine
      List&lt;CountryProjection&gt; findAllProjectedBy(); // works fine
      List&lt;CountryProjection&gt; findAllProjectedBy(Specification&lt;Country&gt; specification); //throws Exception as shown below
  }
  </code></pre>
  
  <p>The first two methods findByName and findAllProjectedBy works fine.
  Whereas the third method findAllProjectedBy(Specification specification) throws the following exception - </p>
  
  <blockquote>
    <p>Caused by: java.util.NoSuchElementException: null     at
    java.util.ArrayList$Itr.next(ArrayList.java:854) ~[na:1.8.0_102]  at
    java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1042)
    ~[na:1.8.0_102]   at
    org.springframework.data.jpa.repository.query.CriteriaQueryParameterBinder.bind(CriteriaQueryParameterBinder.java:63)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:100)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:160)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:151)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.invokeBinding(PartTreeJpaQuery.java:218)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:142)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:78)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:118)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:82)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:482)
    ~[spring-data-commons-1.12.6.RELEASE.jar:na]  at
    org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
    ~[spring-data-commons-1.12.6.RELEASE.jar:na]  at
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]     at
    org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
    ~[spring-data-commons-1.12.6.RELEASE.jar:na]  at
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]     at
    org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    ~[spring-tx-4.3.5.RELEASE.jar:4.3.5.RELEASE]  at
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
    ~[spring-tx-4.3.5.RELEASE.jar:4.3.5.RELEASE]  at
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    ~[spring-tx-4.3.5.RELEASE.jar:4.3.5.RELEASE]  at
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]     at
    org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    ~[spring-tx-4.3.5.RELEASE.jar:4.3.5.RELEASE]  at
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]     at
    org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
    ~[spring-data-jpa-1.10.6.RELEASE.jar:na]  at
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]     at
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]     at
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]     at
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]     at
    com.sun.proxy.$Proxy82.findAllProjectedBy(Unknown Source) ~[na:na]    at
    com.mmp.data.jpa.DataJpaApplication.run(DataJpaApplication.java:42)
    [classes/:na]     at
    org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
    [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]     ... 11 common frames
    omitted</p>
  </blockquote>
  
  <p>How can this be achieved? Any ideas?</p>