Solucionado (ver solução)
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.