We can avoid creating additional methods by using the @Query annotation and adding a small complication to the JPQL statement:
@Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name) and (:email is null"
+ " or c.email = :email)")
List<Customer> findCustomerByNameAndEmail(@Param("name") String name, @Param("email") String email);
Notice that if the: email parameter is null:
:email is null or s.email = :email
Then the clause is always true and so doesn't influence the whole WHERE clause.
Let's make sure that this works:
List<Customer> customers = repository.findCustomerByNameAndEmail("D", null);
assertEquals(2, customers.size());
We found two customers whose name is “D” ignoring their emails.
The generated JPQL WHERE clause looks like this:
where (? is null or customer0_.name=?) and (? is null or customer0_.email=?)
With this method, we are putting trust in the database server to recognize the clause regarding our query parameter being null and optimize the execution plan of the query so that it doesn't have a significant performance overhead. For some queries or database servers, especially involving a huge table scan, there could be a performance overhead.