I'm trying to understand better some deserialization errors I'm seeing in Jackson in a legacy application being converted to a React front-end with Spring back-end.
I see the error when multiple objects of the same class are referenced in the JSON but they have different elements due to fields being ignored with @JsonIgnoreProperties to eliminate infinite recursion. The Spring application will send JSON to the front-end application from the database. We may manipulate a few fields but keep the same basic structure and when we post it back, it says it can't deserialize it. Here's a simplified example.
File named Child.java
public class Child implements java.io.Serializable {
private String name;
@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Parent parent;
public Child() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
File name Parent.java
public class Parent implements java.io.Serializable {
private String name;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@JsonIgnoreProperties("parent")
private Set<Child> children = new HashSet<Child>(0);
public Parent() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Child> getChildren() {
return children;
}
public void setChildren(Set<Child> children) {
this.children = children;
}
}
Controller (normally we would be saving to database here)
@ResponseBody
@RequestMapping(value = "/returnParent", method = RequestMethod.POST)
public ResponseEntity<Parent> returnParent(@RequestBody Child child) throws Exception {
return new ResponseEntity<Parent>(child.getParent(), HttpStatus.OK);
}
JSON posted
{
"name":"child1",
"parent":{
"name":"parent1",
"children":[
{
"name":"child1"
},
{
"name":"child2"
}
]
}
}
Error:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: No _valueDeserializer assigned; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: No _valueDeserializer assigned\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 7, column: 24] (through reference chain: ...Child["parent"]->...Parent["children"]->java.util.HashSet[0]->...Child["name\
I know that if I add this
@JsonIgnoreProperties(value={"children"}, allowGetters=true)
private Parent parent;
to Child that it will suppress the error and ignore child.parent.children but what if we need to be able post back these nested structures? This feels like a bug that it can't read the same JSON it created.