views:

43

answers:

2

I have a city map with streets that I need to (de-)serialize. Each street is identified by City and id, like this:

private final City city;
private final long id;

The city contains a list of all streets in this city (City.streetList), so that when saving the model I can just do something like

serializeToFile(modelFile, currentCity);

This works and causes no problems, but now I want to send the street over the network (also using serialization). When I'm serializing the street, obviously the city Object gets serialized, too, so that all streets will get serialized resulting in very large packet sizes, obviously.

I cannot make city transient, as it is needed to uniquely identify the street. I can also not make City.streetList transient as I will need the list for my model.

Each city has a unique ID, so something like this should be possible

private void writeObject(ObjectOutputStream out) throws IOException {
    if (serializeForNetwork) { // How can I know this here?
        out.writeObject(city.getId());
    } else {
        out.writeObject(city);
    }
    out.write(id);
}

As stated, I have no idea how the object should know it is being written to network (calling street.setWritingToNetwork(true) before serializing seems more than ugly) and maybe this is not a good solution anyway?

Any ideas are very much appreciated! :-)

+2  A: 

If there's no way for you to know that the object is being serialized to a file or over a network, you should always write the city id and not the entire city. Have a way for the city to be looked up given an ID.

Another approach to use is a serialization proxy. See details about it in this pdf :Effective Java Reloaded. Basically serialization proxy is a different class altogether than the object being serialized with the logical state of the object. The object overrides writeReplace and readResolve methods to write a proxy instead of this object and create an object by reading proxy. The proxy will also only write city id and not the entire city.

naikus
+2  A: 

A way out could be redesigning your application, so that your Street object does not contain a reference to city anymore but only a 'city id'. The city objects could go to a separate hash map:

private final long cityId;
private final long id;

and a converter somewhere:

public static City getCity(long id) {
  return cityMap.get(id);
}

the serialized street objects will become quite small and you just have to serialize and store or send the citymap once.

Andreas_D