序列化已经有了id的POJO(java.lang.String) [英] Serializing Already had POJO for id (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实现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)
类Empleadoest实现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,produce = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity< Entrada> getEntrada(@PathVariable(id)String idEntrada){
Entrada entrada = entradaService.get(idEntrada);
if(entrada == null){
返回新的ResponseEntity< Entrada>(HttpStatus.NOT_FOUND);
}
返回新的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());
返回新的ResponseEntity< Void>(标题,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-916 e-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:OPC,
},
}
杰克逊失败:
无法读取HTTP消息:org.springframework.http.converter.HttpMessageNotReadableException:
无法读取文档:已经有用于id的POJO(java。 lang.String)
[[ObjectId:key = 5fb567af-805a-40dc-84bc-8f6038d8cd2f,
type = com.fasterxml.jackson.databind.deser.impl.PropertyBasedObjectIdGenerator,
scope = lt.ciader.model.Empleado]]
(通过参考链:lt.ciader.model.Entrada [representanteTara] - > lt.ciader.model.Empleado [idEmpleado]);
嵌套异常是com.fasterxml.jackson.databind.JsonMappingException:
已经有id的POJO(java.lang.String)
[[ObjectId:key = 5fb567af-805a-40dc-84bc-8f6038d8cd2f,
type = com.fasterxml.jackson.databind.deser.impl.PropertyBasedObjectIdGenerator,
scope = lt.ciader.model.Empleado]]
(通过参考链:lt.ciader.model.Entrada [representanteTara] - > lt.ciader.model.Empleado [idEmpleado])
我知道代表塔拉是同一个代表布鲁托,但它可以是我的模型相同的就业,甚至pesadorTara和PesadorBruto也是如此。
当我使用不同的empleados发送数据时,我的服务获取数据并将其序列化而没有问题。
我用谷歌搜索找到解决方案,但我找不到能帮助我的答案。我查看:
JsonMappingException:已经有了POJO for id
Spring Rest错误第二次使用子属性保存Object,第二次引用同一个父:已经有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
我做错了什么。我该如何解决这个问题。
经过多次测试后我找到了解决方案。问题是杰克逊失败了因为同一个实体出现了两次。该解决方案仅发送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,
},
< blockquote>
representanteTara:5fb567af-805a-40dc-84bc-8f6038d8cd2f,
oficina:{
idEntidad:f3964add-3ae8-4392-bafc-cffb9643ec15,
nombre:OPC,
},
}
I have two entities i serialized and send to client using spring framework 4.2.5 + jacksonjson 2.7.5. My entities are the following:
@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;
}
My REST service end points are
@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);
}
The serialized data I send to the client looks like:
{
"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.",
},
}
But when i try to send data back to the server as following to create a new entity
{
"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 fails:
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"])
I know that representanteTara is the same sa representateBruto but it can be the same employment acoording to my model, even pesadorTara and PesadorBruto too.
When i send data with differents empleados my service get data and serialized it without problems. I googled to find a solution but i can't find an answer that help me. I review:
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
What i doing wrong. How can I solve the problem.
After many test I found a solution. The problem is that Jackson fails becouse the same entity is present two times. The solution is send only the plain ID in the secon instance, not wrapped in object:
{
"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.",
},
}
这篇关于序列化已经有了id的POJO(java.lang.String)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!