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.