序列化已经有了id的POJO(java.lang.String)

我有两个实体,我使用spring framework 4.2.5 + jacksonjson 2.7.5将其序列化并发送给客户端。 我的实体如下:

@Entity @Table(name = "entrada") @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="idEntrada") public class EntradaTest implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "id_entrada", unique = true, nullable = false) private String idEntrada; @Column(nullable = false, length = 5) private String codigo; private Integer recibidos; @ManyToOne @JsonIdentityReference(alwaysAsId = true) @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "idEmpleado", scope = Empleado.class) @JoinColumn(name = "id_pesador_bruto") private Empleado pesadorBruto; @ManyToOne @JsonIdentityReference(alwaysAsId = true) @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "dEmpleado", scope = Empleado.class) @JoinColumn(name = "id_pesador_tara") private Empleado pesadorTara; @ManyToOne @JsonIdentityReference(alwaysAsId = true) @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "idEmpleado", scope = Empleado.class) @JoinColumn(name = "id_representante_bruto") private Empleado representanteBruto; @ManyToOne @JsonIdentityReference(alwaysAsId = true) @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "idEmpleado", scope = Empleado.class) @JoinColumn(name = "id_representante_tara") private Empleado representanteTara; @ManyToOne @JoinColumn(name = "id_oficina", nullable = false) private Entidad oficina; } @Entity @Table(name = "empleado") @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="idEmpleado", scope = Empleado.class) class Empleadoest implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "id_empleado", unique = true, nullable = false) private String idEmpleado; @Column(nullable = false, length = 125) private String nombre; @OneToMany(mappedBy = "pesadorBruto") private Set entradasPesadorBruto; @OneToMany(mappedBy = "pesadorTara") private Set entradasPesadorTara; @OneToMany(mappedBy = "representanteBruto") private Set entradasRepresentanteBruto; @OneToMany(mappedBy = "representanteTara") private Set entradasRepresentanteTara; } 

我的REST服务端点是

 @RequestMapping(value = "/entradas/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity getEntrada(@PathVariable("id") String idEntrada) { Entrada entrada = entradaService.get(idEntrada); if (entrada == null) { return new ResponseEntity(HttpStatus.NOT_FOUND); } return new ResponseEntity(entrada, HttpStatus.OK); } @RequestMapping(value = "/entradas/", method = RequestMethod.POST) public ResponseEntity createEntrada(@RequestBody Entrada entrada, UriComponentsBuilder ucBuilder) { entradaService.save(entrada); HttpHeaders headers = new HttpHeaders(); headers.setLocation(ucBuilder.path("/entradas/{id}").buildAndExpand(entrada.getIdEntrada()).toUri()); return new ResponseEntity(headers, HttpStatus.CREATED); } 

我发送给客户端的序列化数据如下所示:

 { "idEntrada": "e375ecf9-dabd-4c76-8813-0679818f9590", "codigo": "378-2", "recibidos": 0, "pesadorBruto": "0c23c490-a54a-495d-9447-dc6227520646", "pesadorTara": "874dfe26-11cb-48e4-916e-bf8a83187dcb", "representanteBruto": "5fb567af-805a-40dc-84bc-8f6038d8cd2f", "representanteTara": "5fb567af-805a-40dc-84bc-8f6038d8cd2f", "oficina": { "idEntidad": "f3964add-3ae8-4392-bafc-cffb9643ec15", "nombre": "OPC", }, } 

但是当我尝试将数据发送回服务器时,如下所示创建一个新实体

 { "idEntrada":"e375ecf9-dabd-4c76-8813-0679818f9590", "codigo":"378-2", "pesadorBruto":{ "idEmpleado":"0c23c490-a54a-495d-9447-dc6227520646", "nombre":"J. CABRERA", }, "pesadorTara":{ "idEmpleado":"874dfe26-11cb-48e4-916e-bf8a83187dcb", "nombre":"LA DELGADO", }, "representanteBruto":{ "idEmpleado":"5fb567af-805a-40dc-84bc-8f6038d8cd2f", "nombre":"C. MARQUEZ", }, "representanteTara":{ "idEmpleado":"5fb567af-805a-40dc-84bc-8f6038d8cd2f", "nombre":"C. MARQUEZ", }, "oficina":{ "idEntidad":"f3964add-3ae8-4392-bafc-cffb9643ec15", "nombre":"OPC", }, } 

jackson失败了

 Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Already had POJO for id (java.lang.String) [[ObjectId: key=5fb567af-805a-40dc-84bc-8f6038d8cd2f, type=com.fasterxml.jackson.databind.deser.impl.PropertyBasedObjectIdGenerator, scope=lt.ciader.model.Empleado]] (through reference chain: lt.ciader.model.Entrada["representanteTara"]->lt.ciader.model.Empleado["idEmpleado"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Already had POJO for id (java.lang.String) [[ObjectId: key=5fb567af-805a-40dc-84bc-8f6038d8cd2f, type=com.fasterxml.jackson.databind.deser.impl.PropertyBasedObjectIdGenerator, scope=lt.ciader.model.Empleado]] (through reference chain: lt.ciader.model.Entrada["representanteTara"]->lt.ciader.model.Empleado["idEmpleado"]) 

我知道代表塔拉是同一个代表布鲁托,但它可以是我的模型,甚至pesadorTara和PesadorBruto相同的就业。

当我使用不同的empleados发送数据时,我的服务获取数据并将其序列化而没有问题。 我用谷歌搜索找到了解决方案,但我找不到能帮助我的答案。 我回顾:

JsonMappingException:已经有id的POJO

jackson已经有了POJO的身份证

Spring Rest错误第二次保存带有第二次引用同一父的子属性的Object:已经有了id的POJO

https://groups.google.com/forum/#!topic/jackson-user/TSloBi1C_qk

https://github.com/edwinquaihoi/jsonidentitymanytomany/issues/1

https://github.com/FasterXML/jackson-databind/issues/266

我做错了什么。 我该如何解决这个问题。

经过多次测试,我找到了解决方案。 问题是jackson失败了因为同一个实体出现了两次。 解决方案是只发送secon实例中的普通ID,而不是包装在对象中:

 { "idEntrada":"e375ecf9-dabd-4c76-8813-0679818f9590", "codigo":"378-2", "pesadorBruto":{ "idEmpleado":"0c23c490-a54a-495d-9447-dc6227520646", "nombre":"J. CABRERA", }, "pesadorTara":{ "idEmpleado":"874dfe26-11cb-48e4-916e-bf8a83187dcb", "nombre":"LA DELGADO", }, "representanteBruto":{ "idEmpleado":"5fb567af-805a-40dc-84bc-8f6038d8cd2f", "nombre":"C. MARQUEZ", }, 

"representanteTara": "5fb567af-805a-40dc-84bc-8f6038d8cd2f",

 "oficina":{ "idEntidad":"f3964add-3ae8-4392-bafc-cffb9643ec15", "nombre":"OPC", }, }