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

[Bug] Erro ao fazer o mapeamento de retorno no Controller

Oi! Estou desenvolvendo uma nova aplicação. Eu preciso criar um método POST que preciso enviar os seguintes campos: Input:

{
  "forma_pagamento": "D",
  "numero_conta": "234",
  "valor": 10
}

Output:

{
  "id": 1,
  "numero_conta": "234",
  "saldo": 170.07
}

Eu desenvolvi a classe controller, que está montando os campos de entrada, corretamente. O problema está no retorno, que eu não consigo mapear os campos que coloquei no exemplo acima para o output, que retornam na classe de serviço que eu criei, mesmo eu tentando ajustar as classes record (DTO). Poderiam me ajudar, por favor, como que eu faria para ajustar o mapeamento de retorno? Classe controller:

@RestController
@RequestMapping("transacao")
@SecurityRequirement(name = "bearer-key")
public class TransactController {

    @Autowired
    private TransactionService transactionService;

    @PostMapping
    @Transactional
    public ResponseEntity<DataDetailingTransaction> createTransaction(@RequestBody @Valid DataRegistrationTransaction request, UriComponentsBuilder uriBuilder) {
        var transaction = new Transaction(request);
        
        transactionService.saveTransaction(transaction);
        var uri = uriBuilder.path("/transacao/{id}").buildAndExpand(transaction.getId()).toUri();

        return ResponseEntity.created(uri).body(new DataDetailingTransaction(transaction));
    }
}

Classe service:

@Service
@Transactional
@RequiredArgsConstructor
public class TransactionService {

    @Autowired
    private AccountRepository accountRepository;

    @Autowired
    private TransactionRepository transactionRepository;

    public DataDetailingTransaction saveTransaction(Transaction transactions) {
        if (transactions.getNumero_conta() == null) {
            throw new ValidationException("Conta não cadastrada na base de dados.");
        }

        Optional<Transaction> optTransaction = Optional.ofNullable(transactionRepository.findTransactionByAtivoTrue(transactions.getNumero_conta()));

        var valorCalculado = computeTaxTransaction(transactions);

        Optional<Account> optAccount = Optional.ofNullable(accountRepository.findAccountByAtivoTrue(transactions.getNumero_conta()));

        double saldoInicial = 0.0;

        saldoInicial = optAccount.get().getSaldo();

        if (saldoInicial < valorCalculado) {
            throw new ValidationException("Transação não realizada. Saldo indisponível");
        } else {
            double saldo = 0.0;
            saldo = saldoInicial - valorCalculado;

            var account = new Account(optAccount.get().getId(), transactions.getNumero_conta(), saldo, true);
            var saveAccount = accountRepository.save(account);

            boolean existsTransaction = false;
            // Salvar a transação criada no Banco de Dados
            if (optTransaction.isPresent()) {
                if (!optTransaction.get().getId().equals(transactions.getId())) {
                    existsTransaction = true;
                }
            }

            Transaction saveTransaction;

            if (existsTransaction) {
                throw new ValidationException("Não houve registros de transações durante a operação. Id nulo ou inexistente.");
            } else {
                var transaction = new Transaction(transactions.getId(), transactions.getForma_pagamento(), transactions.getNumero_conta(), transactions.getValor(), saldo, account);
                saveTransaction = transactionRepository.save(transaction);
            }

            return new DataDetailingTransaction(saveTransaction);
        }
    }

    private double computeTaxTransaction(Transaction transactions) {
        if (transactions.getForma_pagamento() == null) {
            throw new ValidationException("É obrigatório informar a forma de pagamento para validar o processo de transação.");
        }
        double taxTransaction = 0.0;
        PaymentForm paymentForm = transactions.getForma_pagamento();

        taxTransaction = paymentForm.computeTaxTransaction(transactions.getValor());

        return taxTransaction;
    }
}

Evidências do teste que eu realizei. Segue abaixo o retorno da classe service: Insira aqui a descrição dessa imagem para ajudar na acessibilidadeOs campos que eu preciso retornar para testar a requisição são: -id -numero_conta -saldo

Percebi que o controller está retornando os dados que eu coloquei na entrada, mas não sei como ajustar.

Insira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidade

5 respostas

Oi!

O retorno no seu controller é um objeto do tipo DataDetailingTransaction. Manda aqui o código dessa sua classe

Oi! Segue o código da classe:

package com.banking.account.transact.domain.transaction;

public record DataDetailingTransaction(
        Long id,
        String numero_conta,
        Double saldo) {

    public DataDetailingTransaction(Transaction transaction) {
        this(
                transaction.getId(),
                transaction.getNumero_conta(),
                transaction.getSaldo()
        );
    }
}

Madna também o código da classe Transaction

solução!

Mas acho que o problema é que na sua classe Service o método devolve o objeto DataDetailingTransaction, mas o controller não pega esse retorno e cria outro:

return ResponseEntity.created(uri).body(new DataDetailingTransaction(transaction));

Altere o código no controller:

@PostMapping
@Transactional
public ResponseEntity<DataDetailingTransaction> createTransaction(@RequestBody @Valid DataRegistrationTransaction request, UriComponentsBuilder uriBuilder) {
    var transaction = new Transaction(request);

    var detailingTransaction = transactionService.saveTransaction(transaction);
    
    var uri = uriBuilder.path("/transacao/{id}").buildAndExpand(detailingTransaction.id()).toUri();

    return ResponseEntity.created(uri).body(detailingTransaction);
}

Funcionou, certinho. Obrigado, professor!

Insira aqui a descrição dessa imagem para ajudar na acessibilidade Insira aqui a descrição dessa imagem para ajudar na acessibilidade