Bengt:

I'm enjoying this discussion because of the gymnastics that were required for 
my solutions.  There is no easy way that I am aware of -- but I would LOVE to 
be wrong.

Here's what I did (and, no, I'm not particularly proud of the solution):

(1) For the primary entities, add tracking data (timestamp, user, etc.) plus an 
entityID.
(2) On an update,
        * clone the data in the entity and update the tracking data.  Copy the 
old entityID.
        * mark the previous entity as out-of-date (to speed up searches)
        * persist both entities
(3) On an insert,
        * persist the new entity and increment the entityID
(4) Update the queries to extract only those records where the 'out-of-date' 
flag was not set.

This results in both current and historical entities being preserved in the 
same table.  This will reduce performance as the indices are larger than are 
necessary for daily operation.  This solution can be combined with a nightly 
script which moves out-of-date records from the main table to archived tables.

The entity copy is a real pain but seems to be necessary.  See the 'How to 
persist duplicate of an entity?' thread from January 2011.  As I wrote earlier:

> I would _love_ to have function that would 'reset' a detached entity.  
> Perhaps something like
> 
>       em.detach(myObj);  // ensure that the entity has been detached.
>       OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
>       kem.reset(myObj);
> 
> with the result of the 'reset' operation being a class which is again virgin, 
> i.e.
> 
>       myObj.id == 0
>       myObj.version = 0
>       myObj.pcDetachedState == null
>       myObj.pcStateManager == null
> 
> and so forth for any children.


This would greatly simplify the cloning process.

-=- Jerry





On Jul 7, 2011, at 12:50 PM, Bengt Rodehav [via OpenJPA] wrote:

> I actually use the same approach as Hades for createdBy, updatedBy, 
> createdWhen and updatedWhen. In addition to this basic audit logging I also 
> want to log all historical versions together with information about who 
> updated the object. 
> 
> I've read a little bit about Envers. I didn't want to bring it up since this 
> is an OpenJPA mailing list. It does look interesting but I think it requires 
> Hibernate which I do not intend to go back to. (I'm actually moving away 
> from Hibernate). Also, I'm a bit hesitant to store "copies" of my rows in 
> special audit tables since it also means database migration of those tables. 
> I think serializing the audit log entries and putting them in one column is 
> a better approach from a maintenance perspective. 
> 
> But it would be nice if OpenJPA would provide a callback or some mechanism 
> (even if it's not standard JPA) that would allow further updates/inserts in 
> a callback. 
> 
> Are there any such plans? 
> 
> /Bengt 
> 
> 2011/7/7 Andrew Thompson <[hidden email]> 
> 
> > You might take a look at how hades 
> > ( 
> > http://hades.synyx.org/static/2.x/site/org.synyx.hades/reference/html/auditing.html)
> >  
> > does something close to what you're describing.  Or 
> > http://www.jboss.org/envers
> > 
> > -Andy 
> > 
> > On Thu, 2011-07-07 at 15:35 +0100, David Goodenough wrote: 
> > > On Thursday 07 Jul 2011, 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. I do seem to have the right information available 
> > and 
> > > > the serialization works fine but I don't know how I can persist my 
> > audit 
> > > > log entries at this point. From what I've read, I'm not allowed to use 
> > the 
> > > > entity manager in a "Post" lifecycle callback which of course makes 
> > this 
> > > > hard. 
> > > > 
> > > > What do you recommend? Is there a good place in JPA/OpenJPA where I 
> > > > automatically can trigger the storing of an audit log entry as 
> > described 
> > > > above. Of course I can move this logic up from the persistence layer to 
> > a 
> > > > place where I can first have the entity manager persist my entity and 
> > then 
> > > > explicitly call another service to do the audit log. However, this is a 
> > > > pretty general mechanism that I would like to have automatic support 
> > for in 
> > > > my framework which is why I would like to have it pushed down into the 
> > > > persistence layer. 
> > > > 
> > > > Any ideas? 
> > > > 
> > > > /Bengt 
> > > You could of course cheat. 
> > > 
> > > While you can not access the entiry manager, there is nothing to stop you 
> > > using JDBC.  It would probably not be a good idea to access a table that 
> > > JPA is using, but if this audit trail is write only for this app and only 
> > > read elsewhere that would solve the problem. 
> > > 
> > > David 
> > 
> > 
> 
> 
> If you reply to this email, your message will be added to the discussion 
> below:
> http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6559076.html
> To start a new topic under OpenJPA Users, email 
> ml-node+208411-1703014788-244...@n2.nabble.com 
> To unsubscribe from OpenJPA Users, click here.



--
View this message in context: 
http://openjpa.208410.n2.nabble.com/Audit-log-with-OpenJPA-tp6557932p6559172.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Reply via email to