How to solve circular reference in json serializer caused by hibernate bidirectional mapping?
I rely on Google JSON To handle this kind of issue by using The feature
Excluding Fields From Serialization and Deserialization
Suppose a bi-directional relationship between A and B class as follows
public class A implements Serializable {
private B b;
}
And B
public class B implements Serializable {
private A a;
}
Now use GsonBuilder To get a custom Gson object as follows (Notice setExclusionStrategies method)
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
public boolean shouldSkipClass(Class<?> clazz) {
return (clazz == B.class);
}
/**
* Custom field exclusion goes here
*/
public boolean shouldSkipField(FieldAttributes f) {
return false;
}
})
/**
* Use serializeNulls method if you want To serialize null values
* By default, Gson does not serialize null values
*/
.serializeNulls()
.create();
Now our circular reference
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
String json = gson.toJson(a);
System.out.println(json);
Take a look at GsonBuilder class
Jackson 1.6 (released september 2010) has specific annotation-based support for handling such parent/child linkage, see http://wiki.fasterxml.com/JacksonFeatureBiDirReferences. (Wayback Snapshot)
You can of course already exclude serialization of parent link already using most JSON processing packages (jackson, gson and flex-json at least support it), but the real trick is in how to deserialize it back (re-create parent link), not just handle serialization side. Although sounds like for now just exclusion might work for you.
EDIT (April 2012): Jackson 2.0 now supports true identity references (Wayback Snapshot), so you can solve it this way also.
Can a bi-directional relationship even be represented in JSON? Some data formats are not good fits for some types of data modelling.
One method for dealing with cycles when dealing with traversing object graphs is to keep track of which objects you've seen so far (using identity comparisons), to prevent yourself from traversing down an infinite cycle.