3
respostas

[Dúvida] Erro 500 ao tentar criar o primeiro pagamento com o Postman

Estou tendo problema ao tentar criar o primeiro pagamento com o Postman, erro 500. Parece ser um erro de validação, pesquisei aqui no fórum e, outra vez, parece ser algum problema com o ModelMapper.

Informação importante: Estou utilizando o padrão record no DTO.

Não consegui solucionar esse problema.

List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='não deve ser nulo', propertyPath=pedidoId, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotNull.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve ser nulo', propertyPath=formaDePagamentoId, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotNull.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=nome, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotBlank.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=codigo, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotBlank.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve ser nulo', propertyPath=valor, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotNull.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=expiracao, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotBlank.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=numero, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotBlank.message}'}
]] with root cause

jakarta.validation.ConstraintViolationException: Validation failed for classes [br.com.appfood.ms_pagamentos.model.Pagamento] during persist time for groups [jakarta.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='não deve ser nulo', propertyPath=pedidoId, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotNull.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve ser nulo', propertyPath=formaDePagamentoId, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotNull.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=nome, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotBlank.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=codigo, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotBlank.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve ser nulo', propertyPath=valor, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotNull.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=expiracao, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotBlank.message}'}
    ConstraintViolationImpl{interpolatedMessage='não deve estar em branco

    "status": 500,
    "error": "Internal Server Error",
    "trace": "jakarta.validation.ConstraintViolationException: Validation failed for classes [br.com.appfood.ms_pagamentos.model.Pagamento] during persist time for groups [jakarta.validation.groups.Default, ]... 
        
"message": "Validation failed for classes [br.com.appfood.ms_pagamentos.model.Pagamento] during persist time for groups [jakarta.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage='não deve ser nulo', propertyPath=pedidoId, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotNull.message}'}\n\tConstraintViolationImpl{interpolatedMessage='não deve ser nulo', propertyPath=formaDePagamentoId, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotNull.message}'}\n\tConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=nome, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento, messageTemplate='{jakarta.validation.constraints.NotBlank.message}'}\n\tConstraintViolationImpl{interpolatedMessage='não deve estar em branco', propertyPath=codigo, rootBeanClass=class br.com.appfood.ms_pagamentos.model.Pagamento...
3 respostas

Oi Camilo! Como vai?

Com as atualizações do Spring Boot o ModelMapper não está registrada por padrão como spring bean, logo é apenas uma classe Java normal. Para corrigir isso, você precisa criar uma classe de configuração que definirá o bean, caso queira conectá-lo automaticamente.

Crie um novo package com o nome config e dentro dele crie a classe ModelMapperConfig nele você vai criar um método público com o tipo ModelMapper e dentro dele, retornar uma instância da classe ModelMapper. Segue o código:

@Configuration
public class ModelMapperConfig {

    @Bean
    public ModelMapper criaModelMapper() {
        return new ModelMapper();
    }
}

Após isso, acesse o arquivo PagamentoService e nos métodos que utilizam o modelMapper faça a chamada da função criaModelMapper. Segue o método de pagamento como exemplo:

public Page<PagamentoDto> obterTodos(Pageable paginacao) {
    return repository
            .findAll(paginacao)
            .map(p -> modelMapper.criaModelMapper().map(p, PagamentoDto.class));
}

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Olá! Eu já havia feito isso, de acordo com aula referente a esse problema com o modelMapper. Nessa aula, inclusive, a professora só cria a classe de configuração, depois ela não fez essa chamada nos métodos na classe PagamentoService.

Com essa classe de configuração feita na aula, o projeto começa a rodar normalmente, sem apresentar erros. O erro que aparece é apenas quando vou tentar criar um pagamento, no Postman.

Refiz essa parte utilizando suas dicas, porém, na classe PagamentoService, não começou a aparecer a opção do método para ser chamado.

Segue os códigos para você analisar:

Os métodos abaixo estão como no meu projeto, pois não aparece a opção para chamar o método criado na bean, como você no seu exemplo.

Classe ModelMapperConfig:

package br.com.appfood.ms_pagamentos.config;

import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ModelMapperConfig {

    @Bean
    public ModelMapper criaModelMapper() {
        return new ModelMapper();
    }
}

Método Criar Pagamento:

public PagamentoDto criarPagamento(PagamentoDto dto) {
        Pagamento pagamento = modelMapper.map(dto, Pagamento.class);
        pagamento.setStatus(Status.CRIADO);
        repository.save(pagamento);

        return modelMapper.map(pagamento, PagamentoDto.class);
    }

Método Obter Todos:

  public Page<PagamentoDto> obterTodos(Pageable paginacao) {
        return repository
                .findAll(paginacao)
                .map(p -> modelMapper.map(p, PagamentoDto.class));
    }

Oi, Camilo!

O erro 500 com diversas constraint violations indica que o ModelMapper não está populando corretamente os campos obrigatórios da entidade Pagamento a partir do seu PagamentoDto.

Isso costuma acontecer quando usamos record no DTO e o ModelMapper não consegue inferir corretamente os nomes dos getters e setters, porque eles não existem de fato (só os parâmetros do construtor).

Como o Lombok está um pouco instável nessas versões novas, recomendo que crie os Getters e Setters manualmente nas entidades.

Fico à disposição.