我使用 spring 框架 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<Entrada> entradasPesadorBruto;
@OneToMany(mappedBy = "pesadorTara")
private Set<Entrada> entradasPesadorTara;
@OneToMany(mappedBy = "representanteBruto")
private Set<Entrada> entradasRepresentanteBruto;
@OneToMany(mappedBy = "representanteTara")
private Set<Entrada> entradasRepresentanteTara;
}
我的 REST 服务端点是
@RequestMapping(value = "/entradas/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Entrada> getEntrada(@PathVariable("id") String idEntrada) {
Entrada entrada = entradaService.get(idEntrada);
if (entrada == null) {
return new ResponseEntity<Entrada>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<Entrada>(entrada, HttpStatus.OK);
}
@RequestMapping(value = "/entradas/", method = RequestMethod.POST)
public ResponseEntity<Void> 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<Void>(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": "O.P.C.",
},
}
但是当我尝试如下将数据发送回服务器以创建一个新实体时
{
"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":"L. A. 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":"O.P.C.",
},
}
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"])
我知道 representanteTara 与 representateBruto 相同,但根据我的模型,它可以是相同的工作,甚至 pesadorTara 和 PesadorBruto 也是。
当我使用不同的 empleados 发送数据时,我的服务会毫无问题地获取数据并对其进行序列化。 我用谷歌搜索找到解决方案,但找不到对我有帮助的答案。我回顾:
JsonMappingException: Already had POJO for id
Jackson Already had POJO for id
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 失败了,因为同一个实体出现了两次。解决方案是在第二个实例中只发送普通 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":"L. A. 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":"O.P.C.",
},
}
关于java - 序列化已经有 POJO 的 id (java.lang.String),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42558927/