Serializing Already had POJO for id (java.lang.String)

北城余情 提交于 2020-01-02 09:57:57

问题


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

Spring Rest error the second time that saves Object with child properties that references the same father the second time: 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.


回答1:


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


来源:https://stackoverflow.com/questions/42558927/serializing-already-had-pojo-for-id-java-lang-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!