We are developing a large applications which are related to business. You can find these applications similar to some ERP, CRM, etc.
Now we have a requirement that we ne
It may be just the right time to adopt purely functional lazy data structures.
In a nutshell, this requires banning any mutating operations on your Objects, i.e. making all your Object instances immutable. Then you redesign all the operations which change existing Object to creating new Object instance based on the old one.
For example, let you have an Order
instance which contains a list of OrderItem
s and you need to add a specific OrderItem
to that list. What you do in this case is creating new instance of Order
by replacing its items list by a new list, which in turn is created by cons'ing the new OrderItem
to the old list.
Let me illustrate that example further in pictures. Imagine a storage of objects (let it be RAM or relational database, anything):
Address | Object | Created by --------+--------------------+------------------------------------------ 1000 | list of OrderItems | empty list constructor 1001 | Order | Order constructor, uses address 1000 ... 1300 | OrderItem | ... 1501 | list of OrderItems | cons of addr 1300 to addr 1000 1502 | Order | replace order_items in addr 1001 by addr 1501
The very structure of storing data in this way is persistent (Chris Okasaki elaborates on this in his thesis, for example). You can restore any version of an Object by just following its creation history; versioning becomes trivial. Just remember the main point: don't mutate data, create new instances instead.
I've had to do something similar to this in the past.
I found that the easiest way, if starting from scratch was to add an extra column in the objects data table that held the index of the replacement object. If the value held was zero then I knew that it was the latest version. This also meant that objects were never deleted, although I later added functioanlity that would allow the deletion of the past history.
Effectively the index becomes the version number of the object in question and any query to the DB for the latest version would use the qualifier WHERE NextVersionIndex=0
.
If not starting from scratch this can be implemented into a live system by adding an extra table to store these values - Object Index, Previous version index, next version index.
If you aren't doing invasive (I see generic as competing with invasive), then I think your option is to do full serialization. At each version you just take a snapshot of the object and serialize it to whatever is appropriate.
If you were confined to a database for instance, just save it with a timestamp and take the most recent timestamp as current. I would avoid thinking about it as solely a database problem though. You should be allowed to serialize outside of the system for things like partial results, testing, sanity, etc.
Something along the lines of Hibernate Envers - an Entity Auditing solution, appears to be a good fit for your requirements.
Basically you should be able to compare the fields of an existing object and the new object and persist the differences.
Typically this would be done for highly sensitive entities to keep track of the number of changes to that particular row/account. It would be an overkill if it is done for all the tables. The differences can be persisted asynchronously in a separate history table that matches the same design of the online tables.