Ao fazer a criação do novo get de relatórios, estou com o seguinte problema:
Sendo assim, meu projeto não builda e as minhas tentativas de correção não resolveram. Tentei usar anotação @Repository no TopicoRepository, porém não deu certo. Tentei implementar com o MySQL ao invés do H2 mas sem sucesso também. Minhas classes estão assim:
Repository:
interface TopicoRepository: JpaRepository<Topico, Long> {
fun findByCursoNome(nomeCurso: String, pageable: Pageable): Page<Topico>
@Query("SELECT new br.com.alura.forum.dto.TopicoPorCategoriaDto(curso.categoria, count(t)) FROM Topico t JOIN t.curso curso GROUP BY curso.categoria")
fun relatorio(): List<TopicoPorCategoriaDto>
}
Service:
@Service
class TopicoService(
private val repository: TopicoRepository,
private val topicoViewMapper: TopicoViewMapper,
private val topicoFormMapper: TopicoFormMapper,
private val notFoundMessage: String = "Topico nao encontrado!"
) {
fun listar(nomeCurso: String?, pageable: Pageable): Page<TopicoView> {
val topicos = if (nomeCurso == null) {
repository.findAll(pageable)
} else {
repository.findByCursoNome(nomeCurso, pageable)
}
return topicos.map { t ->
topicoViewMapper.map(t)
}
}
fun buscarPorId(id: Long): TopicoView {
val topico = repository.findById(id)
.orElseThrow { NotFoundException(notFoundMessage) }
return topicoViewMapper.map(topico)
}
fun cadastrar(form: NovoTopicoForm): TopicoView {
val topico = topicoFormMapper.map(form)
repository.save(topico)
return topicoViewMapper.map(topico)
}
fun atualizar(form: AtualizacaoTopicoForm): TopicoView {
val topico = repository.findById(form.id)
.orElseThrow { NotFoundException(notFoundMessage) }
topico.titulo = form.titulo
topico.mensagem = form.mensagem
return topicoViewMapper.map(topico)
}
fun deletar(id: Long) {
repository.deleteById(id)
}
fun relatorio(): List<TopicoPorCategoriaDto> {
return repository.relatorio()
}
}
Controller:
@RestController
@RequestMapping("/topicos")
class TopicoController(
private val service: TopicoService,
private val categoriaDto: TopicoPorCategoriaDto
) {
@GetMapping
@Cacheable("topicos")
fun listar(
@RequestParam(required = false) nomeCurso: String?,
@PageableDefault(size = 5, sort = ["dataCriacao"], direction = Sort.Direction.DESC)
pageable: Pageable,
): Page<TopicoView> {
return service.listar(nomeCurso, pageable)
}
@GetMapping("/{id}")
fun buscarPorId(@PathVariable id: Long): TopicoView {
return service.buscarPorId(id)
}
@PostMapping
@Transactional
@CacheEvict(value = ["topicos"], allEntries = true)
fun cadastrar(
@RequestBody @Valid form: NovoTopicoForm,
uriBuilder: UriComponentsBuilder
): ResponseEntity<TopicoView> {
val topicoView = service.cadastrar(form)
val uri = uriBuilder.path("/topicos/${topicoView.id}").build().toUri()
return ResponseEntity.created(uri).body(topicoView)
}
@PutMapping
@Transactional
@CacheEvict(value = ["topicos"], allEntries = true)
fun atualizar(@RequestBody @Valid form: AtualizacaoTopicoForm): ResponseEntity<TopicoView> {
val topicoView = service.atualizar(form)
return ResponseEntity.ok(topicoView)
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
@Transactional
@CacheEvict(value = ["topicos"], allEntries = true)
fun deletar(@PathVariable id: Long) {
service.deletar(id)
}
@GetMapping("/relatorio")
fun relatorio(): List<TopicoPorCategoriaDto>{
return service.relatorio()
}
}