SpringBoot保存带外键的Address时JSON反序列化错误排查
问题原因
当你在请求JSON中传入"pessoa":1时,Jackson序列化框架尝试将数字1直接反序列化为Pessoa对象,但你的Pessoa类没有提供仅接收Integer类型id参数的构造方法,也没有配置Jackson通过id关联已有实体的规则,因此抛出反序列化异常。
解决方案
以下是三种可行的解决方式,按需选择:
方式1:修改请求JSON格式(无需改代码)
将"pessoa":1改为嵌套对象格式,让Jackson能通过空参构造+setter方法构建Pessoa实例:
{ "logradouro": "test", "cep": "354", "numero": "test", "cidade": "test", "pessoa": {"id": 1} }
方式2:给Pessoa添加带id参数的构造方法
在Pessoa类中添加仅接收id的构造方法,并通过@JsonCreator和@JsonProperty注解告诉Jackson使用该构造方法反序列化:
// 在Pessoa类中新增 @JsonCreator public Pessoa(@JsonProperty("id") Integer id) { this.id = id; }
添加后,你就可以继续使用"pessoa":1的格式发送请求,Jackson会自动调用这个构造方法创建仅包含id的Pessoa对象。
方式3:服务层手动关联数据库实体(更严谨)
如果希望确保关联的是数据库中真实存在的Pessoa,可在EnderecoService中手动查询Pessoa实体后再关联:
// 修改EnderecoServiceImpl的createEndereco方法 @Autowired private PessoaRepository pessoaRepository; @Override public Endereco createEndereco(Endereco endereco) { if (endereco.getPessoa() != null && endereco.getPessoa().getId() != null) { // 查询数据库中存在的Pessoa,避免保存无效外键 Pessoa pessoa = pessoaRepository.findById(endereco.getPessoa().getId()) .orElseThrow(() -> new RuntimeException("Pessoa não encontrada com o id informado")); endereco.setPessoa(pessoa); } return enderecoRepository.save(endereco); }
这种方式下,请求JSON可以用方式1的嵌套对象格式,能有效避免传入不存在的Pessoa id导致的数据库外键错误。
内容的提问来源于stack exchange,提问作者Lemon_prog
相关产品推荐
相关产品推荐

