Adam Warski

16 Jun 2008

Bi-temporal versioning with Envers

envers
java
hibernate

With the recent addition of queries to Envers, it is now possible to easily retrieve data in a bi-temporal way. If you are not familiar with bi-temporal versioning, a good introduction by Martin Fowler can be found here.

Suppose we want to store information about Persons and Addresses, at which these persons live. Moreover, we also want to store dates: when a Person registered the fact that he/she moved, and when did he/she actually move – these may be different, as a person may have first moved, and only registered the fact after a week. Storing the two dates: registered and actual, for some entity, is the basis of bi-temporal versioning.

We can store this information in a Registration entity, which is in a one-to-one relationship with Person, and one-to-many with Address. (Each Person can have at most one Registration, and therefore also Address; each Address can have many Registrations, and therefore many Persons living there.) The Registration entity can also store the registered and actual dates. Additionally, it can be versioned, so that all historical information is remembered.

Using queries, we can, for example, answer this question: “What did we know about the address of person X in the state of the database from date Y?”. To do this, we have to select a registration, which has the actual date as big (recent) as possible, but both the registration and actual dates must be before Y. Hence, the query can look like this:

versionsReader.createQuery()
.forRevisionsOfEntity(Registration.class, true)
  .add(VersionsRestrictions.maximizeProperty("actualDate")
    .add(VersionsRestrictions.relatedIdEq("person", personXId))
    .add(VersionsRestrictions.le("registrationDate", dateY))
    .add(VersionsRestrictions.le("actualDate", dateY)))
.getSingleResult();

You may experiment with bi-temporal versioning using the updated Envers+Seam demo. To run the demo, you’ll need JBoss AS 4.2. After downloading, unzip and deploy the -ds.xml and .ear files, start the server, and go to http://localhost:8080/envers_seam_demo. A screenshot from the demo:

Moreover, the second beta release of Envers is available. It contains minor feature additions (release notes).

Adam

comments powered by Disqus

Any questions?

Can’t find the answer you’re looking for?