Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Utilizando projeções para retornar diretamente um DTO do banco

Certos momentos utilizar o ModelMapper ou mapeamento de beans é meio chato. Ficou ainda mais complicado pra mim que ainda não sei trabalhar com streams. Eu estava convertendo tudo "na mão". Fica ainda mais complicado com a paginação, li em pesquisas que para criar manualmente uma página de DTO é necessário buscar os elementos da página, converter para DTO e depois criar uma nova página. Isto não fica legal. Então decidi utilizar o recurso de projeção do Spring Data para ver se me ajudava um pouco, e ajuda!

1) Mudar o controlador:

@GetMapping
public Page<TopicoDto> listar(@RequestParam(required = false) String nomeCurso, @RequestParam int pagina, @RequestParam int qtd)
{
    Pageable paginacao = PageRequest.of(pagina, qtd);
    if (nomeCurso == null)
    {
        return topicoRepository.findAllProjectedBy(paginacao);
    }
    else
    {            
        return topicoRepository.findByCursoNome(nomeCurso, paginacao);
    }
}

2) Adicionar um construtor na classe TopicoDto que receba as propriedades como parâmetros (as propriedades da classe devem ser iguais as da entidade 'Topico':

public TopicoDto(Long id, String titulo, String mensagem, LocalDateTime dataCriacao)
{
    this.id = id;
    this.titulo = titulo;
    this.mensagem = mensagem;
    this.dataCriacao = dataCriacao;
}

3) Ainda na classe TopicoDto, criar o equals e hashcode obedecendo o equals e hashcode da entidade 'Topico':

@Override
public int hashCode()
{
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
}

@Override
public boolean equals(Object obj)
{
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    TopicoDto other = (TopicoDto) obj;
    if (id == null)
    {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    return true;
}

4) Adicionar os métodos responsáveis pela busca na interface TopicoRepository

Page<TopicoDto> findByCursoNome(String nomeCurso, Pageable paginacao);

Page<TopicoDto> findAllProjectedBy(Pageable paginacao);

Pronto, agora uma página de DTO será respondida ao cliente sem uso de streams, mapeamento de bean ou seja o que for.

Fonte de pesquisa: https://www.baeldung.com/spring-data-jpa-projections e https://stackoverflow.com/questions/50879431/spring-jpa-projection-findall/56751379

1 resposta
solução!

Oi Arthur,

Muito bacana a solução utilizada :)

Outra alternativa para essa parte "chata" de conversão entidade<->dto é utilizar alguma lib que faça isso automaticamente, como a ModelMapper: http://modelmapper.org/

Bons estudos!