title: Dynamic Queries in Spring Data JPA
body: <p>I am looking for a solution to dynamically build queries using Spring Data JPA. I have a GameController which has a RESTful service endpoint /games which takes 4 optional parameters: genre, platform, year, title. The API may be passed none of those, all 4, and every combination in between. If any parameter is not passed it defaults to null. I need a method in the Repository that will build the appropriate query and ideally also still allow Spring Data JPA Paging, although I'm not sure if that is possible.</p>
  
  <p>I found this article but this doesn't seem to be what I need unless I am misunderstanding. <a href="http://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/" rel="noreferrer">http://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/</a></p>
  
  <p>I know JPA has a Query Criteria API but really have no idea how to implement this.</p>
  
  <p>I realize I could create a method for each possible scenario but that seems like really bad practice and a lot of unnecessary code. </p>
  
  <p>GameRepository:</p>
  
  <pre><code>package net.jkratz.igdb.repository;
  
  import net.jkratz.igdb.model.Game;
  import org.springframework.data.domain.Page;
  import org.springframework.data.domain.Pageable;
  import org.springframework.data.jpa.repository.JpaRepository;
  import org.springframework.data.jpa.repository.Query;
  import org.springframework.data.repository.query.Param;
  
  public interface GameRepository extends JpaRepository&lt;Game, Long&gt; {
  
      @Query("select g from Game g, GamePlatformMap gpm, Platform p where g = gpm.game and gpm.platform = p and p.id = :platform")
      Page&lt;Game&gt; getGamesByPlatform(@Param("platform") Long platformId, Pageable pageable);
  
      @Query("select g from Game g where g.title like :title")
      Page&lt;Game&gt; getGamesByTitle(@Param("title") String title, Pageable pageable);
  
      @Query("select g from Game g, GameGenreMap ggm, Genre ge where g = ggm.game and ggm.genre = ge and ge.id = :genreId")
      Page&lt;Game&gt; getGamesByGenre(@Param("genre") Long genreId, Pageable pageable);
  }
  </code></pre>