I'm trying to create an API for saving a Person and its Address, like in this model:
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.