Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Dificuldade para ordenar de forma decrescente a páginação do relatório

Salve, pessoal!

Resolvi implementar uma paginação no endpoint que retorna o relatório com a categoria e quantidade de cada postagem, no entanto eu não consegui realizar a ordenação de forma decrescente. Utilizando 'sort = ["quantidade"]' eu recebo o seguinte erro ao rodar:

{
  "timeStamp": "2022-09-16T09:06:26.5601965",
  "status": 500,
  "error": "INTERNAL_SERVER_ERROR",
  "message": "org.hibernate.QueryException: could not resolve property: quantidade of: br.com.alura.forum.model.Topico [SELECT new br.com.alura.forum.dto.TopicoPorCategoriaDTO(curso.categoria, count(topico)) FROM br.com.alura.forum.model.Topico topico JOIN topico.curso curso GROUP BY curso.categoria order by topico.quantidade desc]; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: quantidade of: br.com.alura.forum.model.Topico [SELECT new br.com.alura.forum.dto.TopicoPorCategoriaDTO(curso.categoria, count(topico)) FROM br.com.alura.forum.model.Topico topico JOIN topico.curso curso GROUP BY curso.categoria order by topico.quantidade desc]",
  "path": "/topicos/relatorio"
}

Acredito que devido a query o modo de realizar essa ordenação seja diferente; gostaria de dicas de como implementar nesse caso.

Seguem os códigos:

//TopicoController
@GetMapping("/relatorio")
    @Cacheable("gerarRelatorio")
    fun gerarRelatorio(
        @PageableDefault(size = 5, sort = ["quantidade"], direction = Sort.Direction.DESC) paginacao: Pageable
    ): Page<TopicoPorCategoriaDTO> {
        return service.gerarRelatorio(paginacao)
    }
//TopicoService
fun gerarRelatorio(paginacao: Pageable): Page<TopicoPorCategoriaDTO> {
        return repository.gerarRelatorio(paginacao)
    }
//TopicoRepository
@Query("SELECT new br.com.alura.forum.dto.TopicoPorCategoriaDTO(curso.categoria, count(topico)) FROM Topico topico JOIN topico.curso curso GROUP BY curso.categoria")
    fun gerarRelatorio(paginacao: Pageable): Page<TopicoPorCategoriaDTO>

Obs: sem o atributo 'sort' na paginação eu recebo um 200 ok:

{
    "content": [
        {
            "categoria": "Banco de Dados",
            "quantidade": 2
        },
        {
            "categoria": "Front-end",
            "quantidade": 3
        },
        {
            "categoria": "Programação",
            "quantidade": 6
        }
    ],
    "pageable": {
        "sort": {
            "empty": true,
            "sorted": false,
            "unsorted": true
        },
        "offset": 0,
        "pageNumber": 0,
        "pageSize": 5,
        "paged": true,
        "unpaged": false
    },
    "last": true,
    "totalPages": 1,
    "totalElements": 3,
    "size": 5,
    "number": 0,
    "sort": {
        "empty": true,
        "sorted": false,
        "unsorted": true
    },
    "first": true,
    "numberOfElements": 3,
    "empty": false
}

Link do repositório:

WybsonSantana/formacao-kotlin-spring-boot-alura

5 respostas

Oi Wybson,

O problema está na sua query:

SELECT 
    new br.com.alura.forum.dto.TopicoPorCategoriaDTO(curso.categoria, count(topico)) 
FROM 
    Topico topico 
JOIN 
    topico.curso curso 
GROUP BY 
    curso.categoria 
ORDER BY 
    topico.quantidade desc

Você está fazendo um order by topico.quantidade, mas na entidade Topico não tem um atributo chamado quantidade.

Suspeitei desde o princípio! Hahahaha ... e qual seria a maneira mais simples de fazer essa implementação?

Acho que no seu caso pode ser assim:

SELECT 
    new br.com.alura.forum.dto.TopicoPorCategoriaDTO(curso.categoria, count(topico) AS quantidade) 
FROM 
    Topico topico 
JOIN 
    topico.curso curso 
GROUP BY 
    curso.categoria 
ORDER BY 
    quantidade desc

Só não tenho certeza se vai funcionar esse alias quantidade e talvez precise repetir o count(topico) no order by.

solução!

Aêeeeeeeeeh! Funcionou!

O código ficou assim:

//TopicoController
@GetMapping("/relatorio")
    @Cacheable("gerarRelatorio")
    fun gerarRelatorio(
        @PageableDefault(size = 5) paginacao: Pageable
    ): Page<TopicoPorCategoriaDTO> {
        return service.gerarRelatorio(paginacao)
    }
//TopicoRepository
@Query("SELECT new br.com.alura.forum.dto.TopicoPorCategoriaDTO(curso.categoria, count(topico) AS quantidade) FROM Topico topico JOIN topico.curso curso GROUP BY curso.categoria ORDER BY quantidade DESC")
    fun gerarRelatorio(paginacao: Pageable): Page<TopicoPorCategoriaDTO>

Valeu demais, Rodrigo!

{
    "content": [
        {
            "categoria": "Programação",
            "quantidade": 6
        },
        {
            "categoria": "Front-end",
            "quantidade": 4
        },
        {
            "categoria": "Banco de Dados",
            "quantidade": 2
        }
    ],
    "pageable": {
        "sort": {
            "empty": true,
            "unsorted": true,
            "sorted": false
        },
        "offset": 0,
        "pageSize": 5,
        "pageNumber": 0,
        "paged": true,
        "unpaged": false
    },
    "last": true,
    "totalElements": 3,
    "totalPages": 1,
    "size": 5,
    "number": 0,
    "sort": {
        "empty": true,
        "unsorted": true,
        "sorted": false
    },
    "first": true,
    "numberOfElements": 3,
    "empty": false
}