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

Duvidas sobre persistência de dados como hibernate

Boa noite pessoal, eu estou desenvolvendo um projeto para praticar os ensinamentos da aula e queria uma ajudinha ! Me deparei com o seguinte questionamento:

  1. Como persistir um Set produtos ; em um banco de dados?

  2. Eu estou recebendo o seguinte erro no console quando chamo o andpoint de solicitacao:

  3. Link do meu repoditório d github: https://github.com/Felipewiiu/Felipewiiu-Projeto_FIAP_Reverselog

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

Classe de Solicitacoes

@Table(name = "solicitacoes")
@Entity(name = "Solicitacao")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class Solicitacao {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String nf_compra;

    @OneToMany(mappedBy = "solicitacao", cascade = CascadeType.ALL)
    private Set<Produto> produto;

    private String descricao_defeito;

    private LocalDateTime data;

    private Boolean ativo = true;

    @Enumerated(EnumType.STRING)
    private Status status;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "cliente_id")

    private Cliente cliente;

    public Solicitacao(RequestDetailData requestRegistrationData) {
        this.nf_compra = requestRegistrationData.nf_compra();
        this.produto = requestRegistrationData.produtos_id();
        this.descricao_defeito = requestRegistrationData.descricao_defeito();
        this.data = requestRegistrationData.data();
        this.status = requestRegistrationData.status();
        this.cliente = requestRegistrationData.cliente();
    }

    public Solicitacao(SolicitacaoDto requestDto) {
        this.nf_compra = requestDto.nf_compra();
        this.produto = requestDto.produto_list();
        this.descricao_defeito = requestDto.descricao_defeito();
        this.data = requestDto.data();
        this.status = requestDto.status();
        this.cliente = requestDto.cliente();
    }


    public void addProduct (Produto product){
        this.produto.add(product);
    }


}

** Classe de Controller**

@RestController
@RequestMapping("/solicitacao")
public class SolicitacaoController {
    @Autowired
    private MakeRequest makeRequest;


    @GetMapping
    public ResponseEntity<Page<RequestRegistrationData>> findAll(Pageable pageable) {
        return ResponseEntity.ok().build();
        // precica criar a lógica de solicitações
    }

    @PostMapping
    @Transactional
    public ResponseEntity registrationRequest(@RequestBody RequestRegistrationData request, UriComponentsBuilder uriBuilder) {
        var dto = makeRequest.Request(request);

        return ResponseEntity.ok(dto);
    }

}

** Classe de Serviço**

package com.company.reverselog.service;

import com.company.reverselog.domain.cliente.ClienteRepository;
import com.company.reverselog.domain.produto.Produto;
import com.company.reverselog.domain.produto.ProdutoRepository;
import com.company.reverselog.domain.solicitacao.RequestDetailData;
import com.company.reverselog.domain.solicitacao.RequestRegistrationData;
import com.company.reverselog.domain.solicitacao.Solicitacao;
import com.company.reverselog.domain.solicitacao.SolicitacaoRepository;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Set;

@Service
@Transactional
public class MakeRequest {
    @Autowired
    private ProdutoRepository productRepository;

    @Autowired
    private ClienteRepository clienteRepository;

    @Autowired
    private SolicitacaoRepository solicitacaoRepository;


    public RequestDetailData Request(RequestRegistrationData data) {
        Set<Produto> products = new HashSet<>();


//        for (Long products_id : data.produto_id()) {
//            var productUnit = productRepository.getReferenceById(products_id);
//            products.add(productUnit);
//
//        }

       data.produto_id().stream().forEach(p -> products.add(productRepository.getReferenceById(p)));

        var cliente = clienteRepository.getReferenceById(data.cliente_id());
        System.out.println(products);
        Solicitacao solicitacao = new Solicitacao();
        solicitacao.setNf_compra(data.nf_compra());
        solicitacao.setProduto(products);
        solicitacao.setDescricao_defeito(data.descricao_defeito());
        solicitacao.setData(data.data());
        solicitacao.setStatus(data.status());
        solicitacao.setCliente(cliente);


        solicitacaoRepository.save(solicitacao);

        return new RequestDetailData(solicitacao);

    }

}
2 respostas
solução!

Isso tá acontecendo porque o Spring está tentando desserializar uma classe do Hibernate, pois o getReferenceById retorna uma referência proxy para o objeto Cliente. Esse acontece quando você tenta responder o request, onde, no seu DTO RequestDetailData, você está passando o objeto Cliente, que nesse momento não é exatamente o objeto Cliente de fato.

Pra evitar isso você pode simplmente chamar algum método get da variável cliente ou usar findById para recupera-lo.

Eu também tomei a liberdade de alterar o construtor de Solicitacao, a própria classe Solicitacao define a data da criação e o status padrão de toda Solicitacao é definido no construtor:

    public Solicitacao(String nf, Set<Produto> produtos, String descricaoDefeito, Cliente cliente) {
        this.data = LocalDateTime.now();
        this.status = Status.ANALISE_DE_GARANTIA;
        
        this.nf_compra = nf;
        this.produto = produtos;
        this.descricao_defeito = descricaoDefeito;
        this.cliente = cliente;
    }

Mas te adianto que, depois de resolver esse erro você vai encontrar problemas de:

  • recursão na resposta
  • coluna null no banco de dados

Acredito que vais precisar rever o relacionamento das suas classes Solicitacao e Produto para conseguir referenciar adequadamento os produtos da sua Solicitacao e evitar essa coluna redundante

Muito obrigado! Descobri também que estou com problemas de relacionamento e preciso corrigir isso.