views:

221

answers:

3

I have mapped several java classes like Customer, Assessment, Rating, ... to a database with Hibernate. Now i am thinking about a history-mode for all changes to the persistent data. The application is a web application. In case of deleting (or editing) data another user should have the possibility to see the changes and undo it. Since the changes are out of the scope of the current session, i don't know how to solve this in something like the Command pattern, which is recommended for undo functionality.

For single value editing an approach like in this question sounds OK. But what about the deletion of a whole persistent entity? The simplest way is to create a flag in the table if this customer is deleted or not. The complexest way is to create a table for each class where deleted entities are stored. Is there anything in between? And how can i integrate these two things in a O/RM system (in my case Hibernate) comfortably, without messing around to much with SQL (which i want to avoid because of portability) and still have enough flexibility?

Is there a best practice?

+2  A: 

One way to do it would be to have a "change history" entity with properties for entity id of the entity changed, action (edit/delete), property name, orginal value, new value. Maybe also reference to the user performing the edit. A deletion would create entities for all properties of the deleted entity with action "delete".

This entity would provide enough data to perform undos and viewing of change history.

Jonas Klemming
+3  A: 

One approach to maintaining audit/undo trails is to mark each version of an object's record with a version number. Finding the current version would be a painful effort if the this were a simple version number, so a reverse version numbering works best. "version' 0 is always the current and if you do an update the version numbers for all previous versions are incremented. Deleting an object is done by incrementing the version numbers on the current records and not inserting a new one at 0.

Compared to an attribute-by-attribute approach this make for far simpler rollbacks or historic version views but does take more space.

Bell
Your approach sounds interesting. I have two questions to this. 1) Where do you store this version number? In the table for the entity itself or in a separated one 2) how do you avoid conflicts with ambiguous Primary Keys for this varying entities which should have always the same keys ? Thank you
Maerch
I generally store the version number in the entity itself. The version number can them be combined with the id field to create a unique primary key.
Bell
A: 

Hmm I'm looking for an answer to this too. So far the best I've found is the www.jboss.org/envers/ framework but even that seems to me like more work than should be necessary.