I have not yet had time to experiment with serialization of groovy objects, but I'm concerned that we need to write our own serialization code to properly handle our domain types. Here's why -- In most serializable types, we have references to non-serializable types. For example, Tariff has a reference to Broker. GORM does lazy fetching, and what's in the table is not the Broker but the Broker's key. But serialization will try to suck in the whole Broker unless it's marked transient, which is not what we want to convey to GORM.
Has anyone worked out how this is supposed to work yet? Do we need to separate serializable types from GORM types? That would be a big pain.
Nguyen Nguyen of the Minnesota group is looking into this. In the meantime I have some thoughts:
Our current design fails to distinguish value types from entity types. A value type is one whose instances are used to carry static information around in a system. Value instances, or simply values, are generally immutable, and the information they carry is often about some entity. Values are distinguished by their content. Entities, on the other hand, are long-lived domain elements that have a lifecycle, are mutable, and are distinguished by some identifying label - a key or ID.
In powertac-common/grails-app/domain, we have examples of both values and entities. Values include CashUpdate, HourlyCharge, Product, Shout, SimulationAction. Entities include Tariff, TariffExaminer, TariffSubscription. Probably Rate is a value, although it contains a list of HourlyCharge instances that is updated (by adding a new one) every hour.
The problem we are having with serialization is perhaps due to our failure to distinguish between references to domain entities and references (or inclusion, in the XML) of domain values. If entities are distinguished by ID and values by content, then domain types should include only the IDs of other entity types, and references to value types.
To rationalize our design, we should make the version of Tariff that is communicated between Broker and Server into a value type, and we should go through all the value types and change entity references to entity IDs. That may mean, for example, that Tariff becomes TariffSpec, while TariffExaminer becomes Tariff, and the mutable portions of the existing Tariff (its state and expiration date, for example) are moved over to the new Tariff (currently TariffExaminer).
One nice result of this would be that the simulation log (the information needed to reconstruct a simulation) would consist only of a series of value objects. That would require that all state changes to entities be represented by a new value. If state changes as a result of a method call, then the entity can create and store a StateChange value, which would look a lot like a Java PropertyChangeEvent.
Suggestion: Perhaps domain Entity types should be in a separate package from domain Value types. Right now they are intermixed. Formerly, we had a separate package org.powertac.common.command for some of the Value types. Many, but not all, of the domain Value types are also used as message payloads, and therefore must be serializable, and any serializable type needs to use ID values for its foreign keys, and not references to other types, unless the intent is to serialize graphs.