I am writing a serializer to serialize POJO to JSON but stuck in circular reference problem. In hibernate bidirectional one-to-many relation, parent references child and child references back to parent and here my serializer dies. (see example code below)
How to break this cycle? Can we get owner tree of an object to see whether object itself exists somewhere in its own owner hierarchy? Any other way to find if the reference is going to be circular? or any other idea to resolve this problem?
views:
412answers:
3Can 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.
I rely on Google JSON To handle this kind of issue by using The feature
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.
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.