JSON 解析错误:已具有用于 ID 的 POJO

2022-09-03 15:29:39

我已经看到了有关此主题的一些问题,但我无法将其应用于我的情况,因为我试图应用它们并且错误仍然存在。所以我来揭露我的情况。

我读了一些关于它的评论,并说如果我在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);
    }


}

enter image description here

enter image description here

enter image description here


答案 1

有两个问题:

1. 标识范围

@JsonIdentityInfo两个类的作用域都应限定为作用域,因为两个类具有相同的生成器类型 - 。ObjectIdGenerators.PropertyGenerator.class

作用域用于定义对象 ID 的适用性:所有 ID 在其作用域内必须是唯一的;其中 scope 定义为此值和生成器类型的组合。比较是简单的等效性,这意味着类型生成器类型和作用域类必须相同。范围用于确定需要多少台发电机;通常,仅当外部对象 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;

当您向 Jackson 反序列化程序传递一个完整的对象(包含内部,如您的示例所示)时。DistritosEntidades

我做了一些调试,发现BeanDeserializer(按名称解析字段)无法反序列化属性字段,因为它的名称与id字段相同,所以我在class中更改为。idEntidadeentidadeDistritos

在进行这些更改后,我的示例项目工作正常(因为我已从您的类中删除了一些字段 - ,以及Entidades中的所有字段)。您必须检查其他类(例如 和 )具有相同的问题,并且也要修复它们。Distritos.idMunicipioDistritos.idUfCollectionMunicipiosUfs


答案 2