Home > Enterprise >  Error when trying to map foreing key in SpringBoot
Error when trying to map foreing key in SpringBoot

Time:01-24

I'm trying to create an API for saving a Person and its Address, like in this model:

Text

And i'm getting this error when trying to save an address with a foreing key:

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: 
Cannot construct instance of `com.apitest.api.model.Pessoa` (although at least one Creator exists): 
no int/Int-argument constructor/factory method to deserialize from Number value (1)]

I know it seems like a parser error, but it just happens when i do a request that contains the fk field, so:

This is a valid request:

{ "logradouro": "test", "cep": "354", "numero": "test", "cidade": "test" }

This one i get a 400 bad request:

{ "logradouro": "null", "cep": "354", "numero": "null", "cidade": "null", "pessoa": 1 }

Just by adding the fk field, like i said.

Models:

Person

package com.apitest.api.model;

import java.util.Date;
import java.util.List;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;

@Entity
@Table(name = "pessoa")
public class Pessoa {




    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;


    @Column(name = "nome")
    private String nome;

    @Column(name = "dataNascimento")
    private Date dataNascimento;

    
    public Pessoa(Integer id, String nome, Date dataNascimento) {
        this.id = id;
        this.nome = nome;
        this.dataNascimento = dataNascimento;
    }

    public Pessoa(){

    };


    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public Date getDataNascimento() {
        return dataNascimento;
    }

    public void setDataNascimento(Date dataNascimento) {
        this.dataNascimento = dataNascimento;
    }

   

 

}

Address


package com.apitest.api.model;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;

@Entity
@Table(name = "endereco")
public class Endereco {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id_endereco;

    @Column(name = "logradouro")
    private String logradouro;

    @Column(name = "cep")
    private String cep;

    @Column(name = "numero")
    private String numero;


    @Column(name = "cidade")
    private String cidade;

    @ManyToOne
    @JoinColumn(name = "id")
    private Pessoa pessoa;

    

    public Endereco(Integer id_endereco, String logradouro, String cep, String numero, String cidade, Pessoa pessoa) {
        this.id_endereco = id_endereco;
        this.logradouro = logradouro;
        this.cep = cep;
        this.numero = numero;
        this.cidade = cidade;
        this.pessoa = pessoa;
    }

    public Endereco(){

    };


    public String getLogradouro() {
        return logradouro;
    }


    public void setLogradouro(String logradouro) {
        this.logradouro = logradouro;
    }


    public String getCep() {
        return cep;
    }


    public void setCep(String cep) {
        this.cep = cep;
    }


    public String getNumero() {
        return numero;
    }


    public void setNumero(String numero) {
        this.numero = numero;
    }


    public String getCidade() {
        return cidade;
    }


    public void setCidade(String cidade) {
        this.cidade = cidade;
    }


    public Pessoa getPessoa() {
        return pessoa;
    }


    public void setPessoa(Pessoa pessoa) {
        this.pessoa = pessoa;
    }


    public Integer getId_endereco() {
        return id_endereco;
    }


    public void setId_endereco(Integer id_endereco) {
        this.id_endereco = id_endereco;
    }

    
}



Controllers:

Person

package com.apitest.api.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.apitest.api.model.Pessoa;

import com.apitest.api.service.PessoaService;

@RestController
public class PessoaController {

    @Autowired
    private PessoaService pessoaService;

    @PostMapping("/pessoas")
    public ResponseEntity<Pessoa> createPessoa(@RequestBody Pessoa pessoa){

        return ResponseEntity.ok().body(this.pessoaService.createPessoa(pessoa));

    }
    
}


Address

package com.apitest.api.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.apitest.api.model.Endereco;
import com.apitest.api.service.EnderecoService;

@RestController
public class EnderecoController {

    @Autowired
    private EnderecoService enderecoService;


    @PostMapping("/endereco")
    public ResponseEntity<Endereco> createEndereco(@RequestBody Endereco endereco){

        return ResponseEntity.ok().body(this.enderecoService.createEndereco(endereco));

    }


    
}

Service:

Person

package com.apitest.api.service;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.apitest.api.model.Pessoa;
import com.apitest.api.repository.PessoaRepository;

@Service
@Transactional
public class PessoaServiceImpl implements PessoaService {

    @Autowired
    private PessoaRepository pessoaRepository;

    @Override
    public Pessoa createPessoa(Pessoa pessoa) {
        return pessoaRepository.save(pessoa);
    }

    @Override
    public Pessoa updatePessoa(Pessoa pessoa) {
        Optional<Pessoa> pessoaDb = this.pessoaRepository.findById(pessoa.getId());
        
        Pessoa pessoaUpdate = pessoaDb.get();
        pessoaUpdate.setId(pessoa.getId());
        pessoaUpdate.setNome(pessoa.getNome());

        return pessoaUpdate;
    }

    @Override
    public Pessoa getPessoaById(Pessoa pessoa) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List<Pessoa> getAllPessoa() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void deletePessoa(long pessoaId) {
        // TODO Auto-generated method stub
        
    }
    
}

Address

package com.apitest.api.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.apitest.api.model.Endereco;
import com.apitest.api.repository.EnderecoRepository;
import com.apitest.api.repository.PessoaRepository;

import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class EnderecoServiceImpl implements EnderecoService {

    @Autowired
    private EnderecoRepository enderecoRepository;


    @Override
    public Endereco createEndereco(Endereco endereco) {

        return enderecoRepository.save(endereco);

    }
    
}

I have already tried to use JsonCreator and JsonProperty annotations but did not worked for me... Any help would be appreciated.

CodePudding user response:

You're getting this error because you're sending the value of "1" for the object Pessoa. You need to pass the fields in the object, something like this should work.

{ "logradouro": "null", "cep": "354", "numero": "null", "cidade": "null", "pessoa": {"id": 1} }

Also, I'm not sure what "null" means here, but if you want those fields to be null, don't send them. The way this is written, you're going to end up with the word null everywhere.

  • Related