Thanks for your post Jim,

In the past (when we rolled our own O/R mapping) we also generated the id's
ourselves via sequences stored in a dedicated table. Come to think of it,
one of the reasons was exactly what you are talking about - one can
reference the id even before the object is persisted. This is of course a
big benefit when it comes to audit logging (and actually other types of
logging as well). I will definitely revisit that.

Your other design decision is also interesting. By having a relationship to
the audit log entries JPA will persist the audit log entry for you - very
convenient indeed. A little similar to the way Pinaki described previously.
However you store the audit log in a separate table while Pinaki stores the
audit log together with the entity (in a separate column) that is being
persisted. I kind of like your approach better. I think an audit log can be
viewed from two different angles: the entity view and the user view. You
need to be able to see what changes have been made to an entity and possibly
even implment undo (like Pinaki). However, you also need to be able to track
all changes done by a specific user during a specific time period. The
latter is much easier with a centralized place for all audit log entries.
Can't really see how that can easily be done with Pinaki's approach.

The only thing I might miss from your solution then is the ability to
configure whether audit logging is enabled for an entity or not. Our
customers have different requirements here. But then again, this should be
possible in your approach as well. In the @PreUpdate method I could check
(somehow) if audit logging is enabled for this entity. If yes, then create
the audit log entry and add it to the collection. If not, then don't create
the audit log entry and nothing will be logged - right?

Have you had the need to configure OpenJPA in some specific way for
performance reasons? I guess you really want to avoid OpenJPA fetching all
your audit log entries every time an entity is fetched...

Also, I need to know whether this is a supported JPA/OpenJPA way of doing
things. My guess is yes since you don't actually use the entity manager
yourself.

Very interesting approach.

Thanks,

/Bengt



2011/7/12 Jim Talbut <jtal...@spudsoft.co.uk>

> On 07/07/2011 12:05, Bengt Rodehav wrote:
>
>> I'm using OpenJPA for persistence and would like to audit log any changes
>> made to my entities. I serialize the objects to JSON (with Gson) and store
>> them in a separate table in the database. Since the audit log needs to
>> have
>> the correct id's, the audit logging must take place after the entity has
>> been persisted.
>>
>> I was hoping I could use the @PostPersist and @PostUpdate life cycle
>> callbacks for this.
>>
> A bit late to the party, but this is what I've got working:
>
> Change the entity ID column so it's not allocated by the database, then it
> becomes valid from the time the entity is persisted, rather than the time
> it's flushed.
> By using a table type sequence generator the disadvantages relative to a
> database generated ID are few (and IME are only seen if you are abusing the
> IDs :) )
>
> I only carry out an audit in @PreUpdate, because all I track is changes and
> there aren't any changes for a new record - so actually the ID generation
> should be irrelevant.
> But by working in PreUpdate I've found that I am able to work with the
> entity manager and create new entities for the audit.
>
> The entity being audited has a OneToMany join to the audit entries, so I
> don't have to call persist on the audit log object, I just add it to the
> collection in the entity being audited.
>
> Jim
>
>

Reply via email to