1
Atualizado
Para o sistema informar id e nome de TODAS as categoria de produto, é só mudar o endpoint. Ou seja, ao invés de retornar Paged no findAllPaged, irá retornar uma lista (service/controller).
Uma requisição exemplo (o que usuário irá informar): /products?page=0&size=12&name=ma&categoryId=1,3
Faremos agora a consulta no Repository para que ele consiga encontrar as categorias e filtrar por nome. A ideia dessa consulta é encontrar os IDS dos Produtos que vão fazer parte da página.
Depois que pegarmos esses Ids dos Produtos, usaremos ele de argumento na outra consulta, que encontrará os produtos com as categorias.
Agora iremos no Repository (Products), e criar o método searchProducts. Seus parâmetros serão exatamente o que está na requisição acima.
Além disso, retornará um Page do tipo ProductProjection.
O ProductProjection irá representar o retorno da consulta SQL feita no h2: id e name.
Agora, é só passar o @Query no método com a consulta customizada. Se for consulta simples: JPQL, mais elaborada: SQL raíz.
Benefício da JPQL é que podemos instanciar a entidade monitorada pela JPA.
Já o SQL raíz, precisamos usar Projection (não monitorada).
Mas o controle que temos da consulta é 100% nosso (usando SQL raíz).
Como nesse caso temos DISTINCT, JOIN, condições de WHERE, usaremos a raíz.