Serializing Object Graphs
Serialization and de-serialization for deep object graphs (references and cyclic dependencies).
Features:
- high-performance graph serialization
- handles cyclic dependencies and polymorphic pojos (interface and abstract classes)
Limitations:
- When a root message is serialized/deserialized, its nested messages should not contain references to it.
Example:
message ClubFounder {
optional string name = 1;
optional Club club = 2;
}
message Club {
optional string name = 1;
repeated Student student = 2;
repeated Club partner_club = 3;
}
message Student {
optional string name = 1;
repeated Club club = 2;
}
You cannot directly serialize Club since it can potentially have a reference to itself.
The solution is to wrap the target message.
message ClubWrapper {
optional Club club = 1;
}
On the other hand, you can serialize ClubFounder.
Schema<ClubFounder> schema = RuntimeSchema.getSchema(ClubFounder.class);
ClubFounder founder = new ClubFounder();
// fill with cyclic club and student objects
byte[] data = GraphIOUtil.toByteArray(founder, schema);
ClubFounder cf = new ClubFounder();
GraphIOUtil.mergeFrom(data, cf, schema);
// check if cf retains the graph
For a more complex example, take a look at PolymorphicRuntimeGraphTest.java
Note that if you have collection fields that can potentially be cyclic, you need to enable the system property below:
-Dprotostuff.runtime.collection_schema_on_repeated_fields=true
E.g
class Foo
{
List<Bar> barList;
List<Baz> anotherBarList; // if this points to barList, it will be cyclic.
}
Doing so treats the collection field as a standalone message (which is handled on cyclic graph serialization).
Source document: https://code.google.com/p/protostuff/wiki/SerializingObjectGraphs