Wow - lots of discussion here. I must have hit a good topic for once...

I don't see why you shouldn't be proud of your solution. Storing all
versions is a well known idiom for preserving your history. Basically you
don't allow updates but create new versions all the time instead. I have
considered it but I'm a bit afraid for the performance impact since
performance is critical.

I've never done this with JPA though. I guess from your mail that it's not
that straight forward. Ideally what you would like is of course to have a
composit key consisting of the id and version together. On every update a
new instance would be persisted with the same id but a higher version.

I don't think the existing version should be updated at all. I would prefer
just creating a new version and leaving the previous (all the previous
versions) intact. Doesn't JPA allow you to do this?

/Bengt

2011/7/7 No1UNo <je...@jerrycarter.org>

> 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