ObjectOutputStreams send incorrect data

The only way to avoid this serious and hard-to-detect error is to ensure that after every object is transmitted, the ObjectOutputStream's records are destroyed. That way it won't recognise any previously seen objects, and will send everything. The record destruction is only done after sending a whole object, so it doesn't damage the system's ability to transmit cyclic structures. Destroying the records also releases memory back to the system.
ObjectOutputStream.reset() is the method to destroy the records.
Of course, that destroys any possibility of even imagining efficiency of any kind, but that's java for you.