Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing historical data with Java and Hibernate

This is a problem about historical data handling. Suppose you have a class MyClass like the following one:

class MyClass {
    String field1;
    Integer field2;
    Long field3;

    getField1() {...}
    setField1(String ...) {...}

    ...
}

Now, suppose I need to make MyClass able to store and retrieve old data, what's the best way to do this?
The requirements are to persist the classes through Hibernate, too. And to have at most two tables per "entity": only one table or one table for the "continuity" class (the one which represents the entity which evolves over the time) and another table for the historical data (as it's suggested here)
Please note that I have to be able to assign an arbitrary valid time to the values of the fields.

The class should have an interface like:

class MyClass {
    // how to store the fields????

    getField1At(Instant i) {...}
    setField1At(Instant i, String ...) {...}

    ...
}

I'm currently using the JTemporal library, and it has a TemporalAttribute<T> class, which is like a map: you can do things like T myAttr.get(Instant i) to get the version of myAttr at Instant i. I know how to persist a TemporalAttribute in a table with Hibernate (it's simple: I persist the SortedMap used by the TemporalAttribute and you get a table with start and end valid time and the value of the attribute).
The real problem is that here we have multiple attributes.
I have a solution in mind but it's not clear, and I'd like to hear your ideas.

like image 704
cdarwin Avatar asked Nov 30 '10 18:11

cdarwin


1 Answers

Your project reminds me of Hibernate Envers.

The Envers project aims to enable easy auditing of persistent classes. All that you have to do is annotate your persistent class or some of its properties, that you want to audit, with @Audited. For each audited entity, a table will be created, which will hold the history of changes made to the entity. You can then retrieve and query historical data without much effort.

  • choose what you want to audit (on a per attribute basis)
  • make your own Revision Entity (that stores informations such as revision number, author, timestamp...)

Using Hibernate Envers for this decouples entities and revision data (in database and in your code).

like image 189
Brian Clozel Avatar answered Sep 24 '22 06:09

Brian Clozel