views:

70

answers:

2

My application uses large trees of domain objects and for most of these objects I'd like to persist some basic information (updatedby, modified time, etc.). I have already added these properties & columns to my application.

I was about to code the setting of these values in all the various constructors, etc. when it occurred to me that the persistence layer should handle this transparently.

But how?

I could certainly do this from within my DAO's, but how to handle the objects that are persisted via a cascade save? Is there a way to intercept the persist() method on those?

What's a good way to implement this capability?

+5  A: 

If you intend to use JPA for the purpose of auditing, you can rely on the PrePersist and PreUpdate callback annotations. The JPA WikiBook has one such example. It helps greatly to have a mapped superclass in this case, otherwise you will continue to do this via "user" space code.

Another way of doing this, is to use triggers (ahem) on tables. This does have a performance impact though. The Openbravo ERP project appears to be using this approach for generating the audit trail.

Update: It is a good idea to have the auditing functionality separated out into a different class, other than the super class of the domain model. JPA Event listeners will help you achieve the same. A good example is present here.

Vineet Reynolds
Pure JPA goodness. Thanks for the tip and the link regarding PrePersist and PreUpdate. As to the idea of storing all auditing information in a single table, it feels like a potential performance bottleneck....no?
HDave
Hmm, that's an interesting question; the answer would depend on what you are storing in the single table and how frequently is it being queried for. If you expect users to query and view audit information relatively a lot during the normal course of operation, you might be better of auditing each entity separately. However, if the audit table is meant to be more or less a SELECT-only table, then it is bound to hurt less, as you have only INSERTs to worry from a performance perspective. I think some amount of capacity planning is required, to anticipate the number of entries in production.
Vineet Reynolds
@Vineet In my particular case, most of the time there will be lots of updates and querying of this info, so I'll continue to store it in the same record as the entity. However, I have a few places where externalizing this information would be a big help.
HDave
+1  A: 

You might want to take a look at Hibernate Envers.

wallenborn
Wow -- Envers is awesome. How did I never hear about it before? Will be giving it serious consideration.
HDave