views:

74

answers:

5

Hi,

Take my domain class for example

public class Person
{
  private Integer id;
  private String name;
  private String address;
  private String telephone;

  //Accessors here..
}

This is great for storing 1 instance of a given Person, however, the name for example would most likely change over time, and I would like to retain any previous values, I may wish to see what addresses this person has lived at over the past 10 years.

What are my options for doing this? This is a Java web app so I could potentially have an AUDIT_LOG table on my schema, but that doesn't sound a very reliable way of keeping track of these changes

Another thought is to have a PersonFamily and keep all instances of person, assuming the last item in the List is the most recent, such as..

 public class PersonFamily
 {
   private Integer id;
   private List<Person> persons;

   //Accessors here...
 }

Any suggestions on how I can achieve this? Is there a really clean and simple process I've missed?

Thanks

A: 

Google for temporal patterns or event sourcing.

http://martinfowler.com/eaaDev/timeNarrative.html

epitka
A: 

There are lots of ways to do it, The simplest would be to have a "Person" which has a list of "PersonHistory" objects. Whenever you call a setter, create a new PersonHistory object with the same values as the most recent. Then alter the changed field, and save that in your list.

The problem with that is you would have a lot of redundant data, one for each change. If this is going to be backed by A database, though rather then storing a huge list, you could dump each old instance to the DB whenever a change is made (so you only store the most recent one in memory)

Otherwise, you could have one list for each variable, and store a Tuple with value and the 'step'. So each time a variable is changed, you update a counter, and store that counter with the value that changed.

Chad Okere
+1  A: 
public class Person
{
  private Integer id;
  private String name;
  private Address address;

 }


public class Address {
  Integer id;
  String line1;
  String line2.
}

Then model this in your database either as :

Person Table

  • id
  • name

Address Table

  • id
  • line1
  • line2

PersonAddressHistory Table with fields:

  • id
  • personId
  • addressId
  • activeDate

the last table maintains a list of the current and previous addresses associated with a person, with the current Address being the last entry (i.e. with max value of id).

Joel
A: 

I think it depends on your usage requirements for the historical data.

For example, with your person example, I would have a "Current / Past" field in the database. For most uses, I would just get the record that is "Current", and it would act as it does now - no changes to DAO or Object model (except perhaps to add start/end timestamps).

When you do require the history, it is likely for very specific reasons, and you can at that time get a separate List ordered by change date. This would be separate to the commonly used data model.

When someone changes their name, clone the Person, change the new record to "Previous", then change the existing record's name, then commit both changes in the same transaction.

Note that if historical data is used very commonly, then the above isn't relevant and you should have a List with first entry being current. This might be the case with address history, which is very commonly used in financial applications. In addition for name changes, the most common change is getting married/divorced, so you should have an extra field - maiden name - in your data model.

JeeBee
+1  A: 

An option you might consider would be a simple version number tied to class:

public class Person 
{
  private Integer id;
  private Integer version;

  private String name;
  private String address;
  private String telephone;

  //additional class stuff...

}

Using this approach, whenever the name, address, or other attributes are updated, the version number is incremented by one. This preserves the original data under the previous version, and allows for easy retrieval of all previous version by id, which does not change.

BCunningham