Search code examples
springspring-datajpql

Spring Data @Query for collections - finding products that belong to at least one category from a given category collection


I want to retrieve all products that contain a given name, and belong to at least one category from a given category collection, using Spring Data.

Doing this by method names works fine (please don't mind portuguese subtleties in field names):

Page<Produto> findDistinctByNomeContainingAndCategoriasIn(String nome, Set<Categoria> categorias, Pageable pageRequest);

My test URI is:

http://localhost:8080/produtos?nome=or&categorias=1,4 

However, I'd like to build the equivalent @Query, but it is not working:

@Query("SELECT DISTINCT obj FROM Produto obj WHERE obj.nome LIKE %:nome% AND obj.categorias IN :categorias")
Page<Produto> findDistinctByNomeContainingAndCategoriasIn(@Param("nome") String nome, @Param("categorias") Set<Categoria> categorias, Pageable pageRequest);

Error in response body:

{
    "timestamp": 1507843414826,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "org.springframework.dao.InvalidDataAccessResourceUsageException",
    "message": "could not prepare statement; SQL [select distinct produto0_.id as id1_10_, produto0_.nome as nome2_10_, produto0_.preco as preco3_10_ from produto produto0_ cross join produto_categoria categorias1_, categoria categoria2_ where produto0_.id=categorias1_.produto_id and categorias1_.categoria_id=categoria2_.id and (produto0_.nome like ?) and (. in (? , ?)) order by produto0_.nome asc limit ?]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement",
    "path": "/produtos"
}

Error in stacktrace:

org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SELECT DISTINCT PRODUTO0_.ID AS ID1_10_, PRODUTO0_.NOME AS NOME2_10_, PRODUTO0_.PRECO AS PRECO3_10_ FROM PRODUTO PRODUTO0_ CROSS JOIN PRODUTO_CATEGORIA CATEGORIAS1_, CATEGORIA CATEGORIA2_ WHERE PRODUTO0_.ID=CATEGORIAS1_.PRODUTO_ID AND CATEGORIAS1_.CATEGORIA_ID=CATEGORIA2_.ID AND (PRODUTO0_.NOME LIKE ?) AND (.[*] IN (? , ?)) ORDER BY PRODUTO0_.NOME ASC LIMIT ? "; expected "), NOT, EXISTS, INTERSECTS, SELECT, FROM, WITH"; SQL statement:
select distinct produto0_.id as id1_10_, produto0_.nome as nome2_10_, produto0_.preco as preco3_10_ from produto produto0_ cross join produto_categoria categorias1_, categoria categoria2_ where produto0_.id=categorias1_.produto_id and categorias1_.categoria_id=categoria2_.id and (produto0_.nome like ?) and (. in (? , ?)) order by produto0_.nome asc limit ? [42001-196]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) ~[h2-1.4.196.jar:1.4.196]

What am I doing wrong? How to build a @Query equivalent to my desired query? Thanks.


Solution

  • you can try

    @Query("SELECT DISTINCT obj FROM Produto obj inner join obj.categorias cat WHERE obj.nome LIKE %:nome% AND cat IN :categorias")
    Page<Produto> findDistinctByNomeContainingAndCategoriasIn(@Param("nome") String nome, @Param("categorias") Set<Categoria> categorias, Pageable pageRequest);
    

    please let me know if it is not work.