Saturday, August 14, 2010

JSON and cyclical references

JSON is a *lightway* data exchange format that does not handle cyclical references between objects. So if you are using for example ORM techniques and you really need to serialize in JSON format you will find depending on the Java API you use an error message like the below (this one comes from json-lib API)
net.sf.json.JSONException: There is a cycle in the hierarchy!
at net.sf.json.util.CycleDetectionStrategy$StrictCycleDetectionStrategy.handleRepeatedReferenceAsObject(CycleDetectionStrategy.java:97)

The solution for the above issue is to mark as transient the offending field. The problem is you do not want to mark it as transient for just everything. Use then annotations.

1. Declare the Annotation interface
public @interface CustomTransient {}
2. Mark your field as transient for your custom serialization
...
@CustomTransient
private Employee[] employees;
...

3. From your library identify the callback to implement property filtering. Below an example for json-lib
jsonConfig = new JsonConfig();
jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
public boolean apply(Object source, String name, Object value) {
try {
Field field = source.getClass().getDeclaredField(name);
Annotation[] annotations = field.getAnnotations();
for(Annotation annotation : annotations) {
if( annotation.toString().equals("@CustomTransient") ){
return true;
}
}
} catch (SecurityException e) {
//Not interested in these cases
e.printStackTrace();
} catch (NoSuchFieldException e) {
//Not interested in these cases
}
return false;
}
});

No comments:

Followers