代码之家  ›  专栏  ›  技术社区  ›  Eduardo Krakhecke

JSON解析错误:id已具有POJO

  •  15
  • Eduardo Krakhecke  · 技术社区  · 8 年前

    所以我来揭露我的情况。

    我读了一些关于它的评论,并说如果我在类Entidade中更改我的列idEntidade的名称,我可能会成功。但我无法更改数据库。

    我试着把 scope= Distritos.class @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "idDistrito")

    我试图使用spring MVC和Angular将数据持久化到数据库中。当我点击保存数据时,我发现了这个错误

    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 .. 
    }
    

    类实体

    @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 . . 
    
        }
    

    @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);
        }
    
    
    }
    

    enter image description here

    enter image description here

    enter image description here

    1 回复  |  直到 8 年前
        1
  •  10
  •   Anatoly Shamov Fildor    8 年前

    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")
    

    @JoinColumn()
    @ManyToOne
    private Entidades idEntidade;
    

    以某种方式干扰

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    private Long idEntidade;
    

    当你传给杰克逊反序列化者一个完整的 地区 实体 内部,如您的示例所示)。

    我做了一些调试,发现 BeanDeserializer (按名称解析字段)未能反序列化属性字段,因为它的名称与id字段相同,所以我更改了 idEntidade entidade 地区

    在这些更改之后,我的示例项目运行良好(因为我已经从类中删除了一些字段)- Distritos.idMunicipio Distritos.idUf Collection 来自实体)。如果其他课程(例如。 Municipios Ufs )有同样的问题,也要解决。

    推荐文章