JSON解析错误:已经有POJO for id
Posted
技术标签:
【中文标题】JSON解析错误:已经有POJO for id【英文标题】:JSON parse error: Already had POJO for id 【发布时间】:2018-03-11 15:43:17 【问题描述】:我已经看到了一些关于这个主题的问题,但我无法将它应用到我的案例中,因为我试图应用它们并且错误继续存在。 所以我来暴露我的情况。
我读了一些关于它的 cmets,并说如果我在 Entidade 类中更改我的列 idEntidade 的名称,我可以成功。但我不能改变数据库。
我试图将scope= Distritos.class
放入我的@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "idDistrito")
,但没有成功。
我需要帮助。
我正在尝试使用带有 Angular 的 spring MVC 将数据保存在我的数据库中。当我点击保存数据时出现此错误
2017-09-29 13:28:02.126 WARN 2716 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Already had POJO for id (java.lang.Long) [[ObjectId: key=1, type=com.fasterxml.jackson.databind.deser.impl.PropertyBasedObjectIdGenerator, scope=java.lang.Object]]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Already had POJO for id (java.lang.Long) [[ObjectId: key=1, type=com.fasterxml.jackson.databind.deser.impl.PropertyBasedObjectIdGenerator, scope=java.lang.Object]] (through reference chain: digifred.global.model.Distritos["idEntidade"]->digifred.global.model.Entidades["idEntidade"])
2017-09-29 13:28:02.126 WARN 2716 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Already had POJO for id (java.lang.Long) [[ObjectId: key=1, type=com.fasterxml.jackson.databind.deser.impl.PropertyBasedObjectIdGenerator, scope=java.lang.Object]]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Already had POJO for id (java.lang.Long) [[ObjectId: key=1, type=com.fasterxml.jackson.databind.deser.impl.PropertyBasedObjectIdGenerator, scope=java.lang.Object]] (through reference chain: digifred.global.model.Distritos["idEntidade"]->digifred.global.model.Entidades["idEntidade"])
2017-09-29 13:46:14.096 INFO 2716 --- [ Thread-46] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@53b2ae5: startup date [Fri Sep 29 13:23:36 BRT 2017]; root of context hierarchy
我有这些课
@Entity
@Table(name = "distritos", schema="glb")
@XmlRootElement
@NamedQueries(
@NamedQuery(name = "Distritos.findAll", query = "SELECT d FROM Distritos d"),
@NamedQuery(name = "Distritos.findByIdDistrito", query = "SELECT d FROM Distritos d WHERE d.idDistrito = :idDistrito"),
@NamedQuery(name = "Distritos.findByNome", query = "SELECT d FROM Distritos d WHERE d.nome = :nome"),
@NamedQuery(name = "Distritos.findByCodigoDne", query = "SELECT d FROM Distritos d WHERE d.codigoDne = :codigoDne"),
@NamedQuery(name = "Distritos.findByFlagAtivo", query = "SELECT d FROM Distritos d WHERE d.flagAtivo = :flagAtivo"))
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "idDistrito")
public class Distritos implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id_distrito")
private Long idDistrito;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 70)
@Column(name = "nome")
private String nome;
@Size(max = 8)
@Column(name = "codigo_dne")
private String codigoDne;
@Column(name = "flag_ativo")
private Integer flagAtivo;
@JoinColumn()
@ManyToOne
private Entidades idEntidade;
@JoinColumn()
@ManyToOne(optional = false)
private Municipios idMunicipio;
@JoinColumn()
@ManyToOne(optional = false)
private Ufs idUf;
gets and sets ..
类Entidades
@Entity
@Table(name = "entidades", schema="glb")
@XmlRootElement
@NamedQueries(
@NamedQuery(name = "Entidades.findAll", query = "SELECT e FROM Entidades e"),
@NamedQuery(name = "Entidades.findByIdEntidade", query = "SELECT e FROM Entidades e WHERE e.idEntidade = :idEntidade"),
@NamedQuery(name = "Entidades.findByBairro", query = "SELECT e FROM Entidades e WHERE e.bairro = :bairro"),
@NamedQuery(name = "Entidades.findByBrasao", query = "SELECT e FROM Entidades e WHERE e.brasao = :brasao"),
@NamedQuery(name = "Entidades.findByCnpj", query = "SELECT e FROM Entidades e WHERE e.cnpj = :cnpj"),
@NamedQuery(name = "Entidades.findByComplemento", query = "SELECT e FROM Entidades e WHERE e.complemento = :complemento"),
@NamedQuery(name = "Entidades.findByEmail", query = "SELECT e FROM Entidades e WHERE e.email = :email"),
@NamedQuery(name = "Entidades.findByLogradouro", query = "SELECT e FROM Entidades e WHERE e.logradouro = :logradouro"),
@NamedQuery(name = "Entidades.findByNome", query = "SELECT e FROM Entidades e WHERE e.nome = :nome"),
@NamedQuery(name = "Entidades.findByNumero", query = "SELECT e FROM Entidades e WHERE e.numero = :numero"),
@NamedQuery(name = "Entidades.findBySigla", query = "SELECT e FROM Entidades e WHERE e.sigla = :sigla"),
@NamedQuery(name = "Entidades.findByTelefone", query = "SELECT e FROM Entidades e WHERE e.telefone = :telefone"))
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "idEntidade")
public class Entidades implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
private Long idEntidade;
@Size(max = 50)
private String bairro;
private BigInteger brasao;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 14)
private String cnpj;
@Size(max = 20)
private String complemento;
// @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`|~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`|~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="E-mail inválido")//if the field contains email address consider using this annotation to enforce field validation
@Size(max = 30)
private String email;
@Size(max = 50)
private String logradouro;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 70)
private String nome;
@Size(max = 20)
private String numero;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 4)
private String sigla;
@Size(max = 12)
private String telefone;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idEntidade")
private Collection<EntidadesAdministradores> entidadesAdministradoresCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "entidades")
private Collection<Bairros> bairrosCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idEntidade")
private Collection<PessoasDeficiencias> pessoasDeficienciasCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idEntidade")
private Collection<PessoasEnderecos> pessoasEnderecosCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idEntidade")
private Collection<EntidadesLicencas> entidadesLicencasCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idEntidade")
private Collection<PessoasContatos> pessoasContatosCollection;
@OneToMany(mappedBy = "idEntidade")
private Collection<Logradouros> logradourosCollection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idEntidade")
private Collection<Pessoas> pessoasCollection;
@JoinColumn()
@ManyToOne(optional = false)
private Municipios idMunicipio;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "idEntidade")
private Collection<PessoasCaracteristicas> pessoasCaracteristicasCollection;
public Entidades()
.... gets and sets . .
类 DistritosController
@RestController
@RequestMapping(value="/user")
public class DistritosController
@Autowired
DistritosService distritosService;
@RequestMapping(method = RequestMethod.POST, value = "/distritos", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Distritos> cadastrarDistritos(@RequestBody Distritos distritos)
Distritos distritosCadastrado = distritosService.cadastrar(distritos);
return new ResponseEntity<Distritos>(distritosCadastrado, HttpStatus.CREATED);
@RequestMapping(method = RequestMethod.GET, value = "/distritos", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<Distritos>> buscarTodosDistritos()
Collection<Distritos> distritosBuscados = distritosService.buscarTodos();
return new ResponseEntity<>(distritosBuscados, HttpStatus.OK);
@RequestMapping(method = RequestMethod.GET, value = "/distritos/id", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Distritos> buscarDistritosPorId(@PathVariable int id)
Distritos distritos = distritosService.buscaPorId(id);
return new ResponseEntity<>(distritos, HttpStatus.OK);
@RequestMapping(method = RequestMethod.DELETE, value = "/distritos/id")
public ResponseEntity<Distritos> excluirDistritos(@PathVariable int id)
Distritos distritoEncontrado = distritosService.buscaPorId(id);
if (distritoEncontrado == null)
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
distritosService.excluir(distritoEncontrado);
return new ResponseEntity<>(HttpStatus.OK);
@RequestMapping(method = RequestMethod.PUT, value = "/distritos", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Distritos> alterarDistritos(@RequestBody Distritos distritos)
Distritos distritoAlterado = distritosService.alterar(distritos);
return new ResponseEntity<Distritos>(distritoAlterado, HttpStatus.OK);
【问题讨论】:
您可以在不更改数据库的情况下更改 idEntidade 属性名称。@JoinColumn(name="idEntidade")
并选择您想要的名称。
@Genu 我一直在尝试,但仍然没有成功
您能否发布一个发送到服务器的实际 JSON 示例?
@brain99 我用 API 的响应编辑了问题
当我将scope= Distritos.class
放入我的@JsonIdentityInfo
时,我得到了一个不同的错误。ERRO: valor nulo na coluna "id_municipio" viola a restrição não-nula Detalhe: Registro que falhou contém (31, 00008, null, disss, null, null, 1).
【参考方案1】:
有两个问题:
1。身份范围
@JsonIdentityInfo
的两个都应该是作用域的,因为你的两个类都具有相同的生成器类型 - ObjectIdGenerators.PropertyGenerator.class
。
范围用于定义对象 ID 的适用性:所有 ID 必须是 在他们的范围内是独一无二的;其中范围定义为 此值和生成器类型。比较是简单的等价, 这意味着类型生成器类型和作用域类都必须是 相同的。范围用于确定需要多少个生成器; 通常只有在外部对象 ID 时才需要多个范围 具有重叠的值域(即仅在某些范围内是唯一的 范围有限)
对于Distritos
:
@JsonIdentityInfo(scope = Distritos.class, generator = ObjectIdGenerators.PropertyGenerator.class, property = "idDistrito")
对于Entidades
:
@JsonIdentityInfo(scope = Entidades.class, generator = ObjectIdGenerators.PropertyGenerator.class, property = "idEntidade")
2。字段命名
@JoinColumn()
@ManyToOne
private Entidades idEntidade;
以某种方式干扰
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
private Long idEntidade;
当您将完整的 Distritos
对象传递给 Jackson 反序列化器时(内部包含 Entidades
,如您的示例所示)。
我做了一些调试,发现BeanDeserializer(通过名称解析字段)无法反序列化属性字段,因为它与id字段命名相同,所以我将@中的idEntidade
更改为entidade
987654335@班级。
在这些更改之后,我的示例项目工作正常(因为我已经从您的课程中删除了一些字段 - Distritos.idMunicipio
、Distritos.idUf
以及来自 Entidades 的所有 Collection
s)。您必须检查其他类(例如 Municipios
和 Ufs
)是否有相同的问题,并修复它们。
【讨论】:
以上是关于JSON解析错误:已经有POJO for id的主要内容,如果未能解决你的问题,请参考以下文章
如何将查询的结果集转换为可以进一步解析以创建json的pojo类?
使用 gson 解析成 POJO 时,Json 总是返回 null
使用Jackson“意外令牌(START_OBJECT)使用LocalDateTime将JSON解析为POJO,预期VALUE_STRING:预期的数组或字符串。”