Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
16
respostas

[Bug] erro ao carregar uma entidade no método listar do controller

o método

@GetMapping
public ResponseEntity<Page<DadosDetalheProposta>> listar(@PageableDefault(size = 10, sort = {"descricao"}) Pageable paginacao) {
    var proposta = propostaService.listar(paginacao);
    return ResponseEntity.ok(proposta);
}

do controller de protosta está dando erro ao carregar os dados da entidade(é uma classe).

método do service:  
public Page<DadosDetalheProposta> listar(Pageable paginacao) {
    return repository.findAll(paginacao)
            .map(proposta -> new DadosDetalheProposta(proposta));
}

record:

package br.com.connect.crm.domain.proposta.vo;

import br.com.connect.crm.domain.entidade.entity.Entidade;
import br.com.connect.crm.domain.proposta.entity.Proposta;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;

public record DadosDetalheProposta(
        Long id,
        Integer numero,
        String descricao,
        LocalDate data,
        BigDecimal valor,
        Entidade entidade,
        TipoProposta tipo,
        StatusProposta status) implements Serializable {

    public DadosDetalheProposta(Long id, Integer numero, String descricao, LocalDate data, BigDecimal valor, Entidade entidade, TipoProposta tipo, StatusProposta status) {
        this.id = id;
        this.numero = numero;
        this.descricao = descricao;
        this.data = data;
        this.valor = valor;
        this.entidade = entidade;
        this.tipo = tipo;
        this.status = status;
    }
public DadosDetalheProposta(Proposta proposta) {
    this(
            proposta.getId(),
            proposta.getNumero(),
            proposta.getDescricao(),
            proposta.getData(),
            proposta.getValor(),
            new Entidade(
                    proposta.getEntidade().getId(),
                    proposta.getEntidade().getNome(),
                    proposta.getEntidade().getTipo()
            ),
            proposta.getTipo(),
            proposta.getStatus()
    );
}

classe :

package br.com.connect.crm.domain.proposta.entity;

import br.com.connect.crm.domain.entidade.entity.Entidade;
import br.com.connect.crm.domain.proposta.vo.DadosDetalheProposta;
import br.com.connect.crm.domain.proposta.vo.DadosProposta;
import br.com.connect.crm.domain.proposta.vo.StatusProposta;
import br.com.connect.crm.domain.proposta.vo.TipoProposta;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.time.LocalDate;

@Entity
@Table(name = "propostas")
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Proposta {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Integer numero;
    private String descricao;
    private LocalDate data;
    private BigDecimal valor;
    @Enumerated(EnumType.STRING)
    private TipoProposta tipo;
    @Enumerated(EnumType.STRING)
    private StatusProposta status;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "entidade_id")
    private Entidade entidade;

    public Proposta(DadosProposta dados, Entidade entidade) {
        this.numero = dados.numero();
        this.descricao = dados.descricao();
        this.data = dados.data();
        this.valor = dados.valor();
        this.tipo = dados.tipo();
        this.entidade = entidade;
        this.status = dados.status();
    }

    public void atualizarDados(DadosProposta dados) {
        this.numero = dados.numero();
        this.descricao = dados.descricao();
        this.data = dados.data();
        this.valor = dados.valor();
        this.tipo = dados.tipo();
        this.entidade = entidade;
        this.status = dados.status();
    }

    public Proposta(DadosDetalheProposta dados) {
        this.id = dados.id();
        this.numero = dados.numero();
        this.descricao = dados.descricao();
        this.valor = dados.valor();
        this.tipo = dados.tipo();
        this.entidade = entidade;
        this.status = dados.status();
    }

}
16 respostas

Oi!

Que erro que está acontecendo?

boa tarde, está retornando assim: { "content": [ { "id": 1, "numero": 1787, "descricao": "PROJETO MICRO GERAÇÃO (ATÉ 75 kW)", "data": "2024-06-11", "valor": 16218.19, "entidade": null, "tipo": "COMERCIAL", "status": "ABERTA" } ], "page": { "size": 10, "number": 0, "totalElements": 1, "totalPages": 1 } }, não está trazendo os dados da entidade, que seriam: o nome e o tipo ex: fulado de tal, cliente

package br.com.connect.crm.domain.proposta.entity;

import br.com.connect.crm.domain.entidade.entity.Entidade; import br.com.connect.crm.domain.proposta.vo.DadosDetalheProposta; import br.com.connect.crm.domain.proposta.vo.DadosProposta; import br.com.connect.crm.domain.proposta.vo.StatusProposta; import br.com.connect.crm.domain.proposta.vo.TipoProposta; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor;

import java.math.BigDecimal; import java.time.LocalDate;

@Entity @Table(name = "propostas") @Getter @NoArgsConstructor @AllArgsConstructor public class Proposta { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Integer numero; private String descricao; private LocalDate data; private BigDecimal valor; @Enumerated(EnumType.ORDINAL) private TipoProposta tipo; @Enumerated(EnumType.ORDINAL) private StatusProposta status;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_entidade")
private Entidade entidade;

public Proposta(DadosProposta dados, Entidade entidade) {
    this.numero = dados.numero();
    this.descricao = dados.descricao();
    this.data = dados.data();
    this.valor = dados.valor();
    this.tipo = dados.tipo();
    this.entidade = entidade;
    this.status = dados.status();
}

public void atualizarDados(DadosProposta dados) {
    this.numero = dados.numero();
    this.descricao = dados.descricao();
    this.data = dados.data();
    this.valor = dados.valor();
    this.tipo = dados.tipo();
    this.entidade = entidade;
    this.status = dados.status();
}

public Proposta(DadosDetalheProposta dados) {
    this.id = dados.id();
    this.numero = dados.numero();
    this.descricao = dados.descricao();
    this.valor = dados.valor();
    this.tipo = dados.tipo();
    this.entidade = entidade;
    this.status = dados.status();
}

}

package br.com.connect.crm.domain.entidade.entity;

import br.com.connect.crm.domain.entidade.vo.DadosDetalheEntidade; import br.com.connect.crm.domain.entidade.vo.DadosEntidade; import br.com.connect.crm.domain.entidade.vo.TipoEntidade; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor;

@Entity @Table(name = "entidades") @Getter @NoArgsConstructor @AllArgsConstructor public class Entidade {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nome;

@Enumerated(EnumType.ORDINAL)
private TipoEntidade tipo;

public Entidade(DadosEntidade dados) {
    this.nome = dados.nome().toUpperCase();
    this.tipo = dados.tipo();
}

public void atualizarDados(DadosEntidade dados) {
    this.nome = dados.nome();
    this.tipo = dados.tipo();
}

public Entidade(DadosDetalheEntidade dados) {
    this.id = dados.id();
    this.nome = dados.nome();
    this.tipo = dados.tipo();
}

}

package br.com.connect.crm.domain.proposta.vo;

import br.com.connect.crm.domain.entidade.entity.Entidade; import br.com.connect.crm.domain.proposta.entity.Proposta;

import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate;

public record DadosDetalheProposta( Long id, Integer numero, String descricao, LocalDate data, BigDecimal valor, Entidade entidade, TipoProposta tipo, StatusProposta status) implements Serializable {

public DadosDetalheProposta(Long id, Integer numero, String descricao, LocalDate data, BigDecimal valor, Entidade entidade, TipoProposta tipo, StatusProposta status) {
    this.id = id;
    this.numero = numero;
    this.descricao = descricao;
    this.data = data;
    this.valor = valor;
    this.entidade = entidade;
    this.tipo = tipo;
    this.status = status;
}

public DadosDetalheProposta(Proposta proposta) {
    this(
            proposta.getId(),
            proposta.getNumero(),
            proposta.getDescricao(),
            proposta.getData(),
            proposta.getValor(),
            proposta.getEntidade(),
            proposta.getTipo(),
            proposta.getStatus()
    );
}

}

A principio o código está correto.

Confere no banco de dados, na sua tabela de propostas, se a proposta salva tem a coluna id_entidade preenchida ou se foi salva como null.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade Boa tarde, o valor da entidade está salvo no banco

erro no backend: 2024-06-11T17:45:54.968-03:00 WARN 9840 --- [connect-crm] [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: could not initialize proxy [br.com.connect.crm.domain.entidade.entity.Entidade#4] - no Session]

solução!

Você vai precisar alterar a sua consulta no repository para carregar a entidade junto com a proposta, pois esse relacionamento está configurado como LAZY:

@Query("SELECT p FROM Proposta p JOIN FETCH p.entidade")
Page<Proposta> findAll(Pageable paginacao);

Boa tarde, Rodrigo.

Fiz da forma que você orientou, mas o erro persiste.

Consegue compartilhar seu projeto? Se não puder, mande aqui como ficou as suas classes Service e Repository

Segue o link do github: https://github.com/goethecarvalho/connect-crm-api

Testei aqui localmente e funcionou:

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

Reinicie o projeto.

Rodrigo, o que você diz por reiniciar o projeto? Seria parar e iniciar novamente a aplicação? No meu caso eu utilizo o intellij, e fiz isso, porém o problema persiste.

Parar a classe main e executar novamente. Vi que você está utilizando cache com Redis e ele pode estar interferindo, trazendo dados anteriores que estavam em cache.

Removi as anotações do redis e funcionou.

Obrigado, Rodrigo.