Recently we had a big issue with sending JSON in our Java Web App with Jackson. We had a pretty complex entity model and bidirectional references and used therefore @JsonIdentityInfo. @JsonManagedReference and @JsonBackReference didn't work because it was bidirectional.
At first we had the problem with duplicate properties:
{
"links": [{
"id": 2,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [{
"linkLabel": 1,
"linkLabel": "after"
}]
}, {
"id": 5,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [{
"linkLabel": 2,
"linkLabel": "before"
}, {
"linkLabel": 3,
"linkLabel": "overlap"
}, 1]
}, {
"id": 3,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [3]
}
}
As you can see linkLabel appears twice. This was because we used an IntSequenceGenerator on a String attribute:
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "linkLabel")
public class LinkLabel implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@JsonFormat(shape = JsonFormat.Shape.STRING)
@Column(name = "LinkLabel")
@GeneratedValue(strategy = GenerationType.AUTO)
private String linkLabel;
Then we had the problem that with the once encountered objects in the JSON are replaced by there ids with @JsonIdentityInfo:
{
"objects": [{
"id": 1,
"otherObj": [{
"id": 1,
...
}, {
"id": 3,
...
}]
},
"id": 2,
"otherObj": [1] <-- referencing otherObj with id 1
]
}
This is the Java Entity:
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "linkLabel")
public class LinkLabel implements Serializable {
//...
}
This behavior was a big problem on the JavaScript/ AngularJS client side. Fortunately we found the Jackson-Jsog plugin https://github.com/jsog/jsog-jackson. It can handle bidirectional references easily and can be used on client side as well.
So the code now looks like this:
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.voodoodyne.jackson.jsog.JSOGGenerator;
@Entity
@JsonIdentityInfo(generator=JSOGGenerator.class)
public class LinkLabel implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "LinkLabel")
@GeneratedValue(strategy = GenerationType.AUTO)
private String linkLabel;
}
Simply add it in your pom.xml and on client side in your bower.json. It works like a charm!