Anodos wrote:
I see that a frequent question is how to keep a history of every version of an object. I have this same need myself. I have also seen a lot of complex solutions to this problem (one involving DB triggers and views, another involving a complicated custom interceptor, etc).
But it seems to me there could be a much simpler solution. We already use an integer "version" field for optimistic locking in all our Hibernate POJOs, so why not INSERT instead of UPDATE whenever an object is updated? The previous versions of the object would now exist in the table. Of course, part of the beauty of an UPDATE is that you can use the WHERE clause to do your optimistic locking check, but if you rolled the version field into the primary key of the object then that could be used to perform the version check without having to issue any additional SQL (in this case, you would get a unique constraint violation from the DB if the optimistic locking check fails, which you would check for and convert into an optimistic locking failure exception of some sort). Getting an object by its id would entail something along the lines of "select * from table where id = ? order by version desc limit 1", which, of course, Hibernate could do automatically behind the scenes for you.
I realize that there are disadvantages to this approach and some people do not want this kind of a solution, but I believe there is still a large set of users that could benefit, myself included. So, my question is, can this be accomplished in Hibernate 3 today, and if so, how? Of course, I realize this could be done manually (I could manually increment a version field that is part of the PK), so the whole essence of my question is, can Hibernate 3 be made to automatically accomodate this particular "version" scenario without special or custom coding on my part?
Thanks!
I think that's the only solution that's possible. Do inserts instead of updates. Add a field called "version number". Do "select ... where ... order by version number desc limit 1".
For some applications, like a chat system or something where the data are "throw-away", plain old updates are fine. For things like accounting, where no data should ever be thrown away, this is the way to do it.
I think that under the hood, this is how databases work anyway. When you do an update, it actually inserts a new record and marks the old record as "deleted".
Some applications need versioning and some don't.
I'm working on a web-to-POJO framework to simplify all this. It has a servlet called EditServlet which is used for updating objects. The same servlet is used for all objects of all classes; you don't need to write a servlet to go with every class. Anyway, one of the options in this edit servlet will be a versioning option.
One thing that versioning would change is the way you handle associations. For example, if I have a "Customer" object and I want it versioned, I would probably have the Address object be a separate entity, not a component, so I could make versioned changes to the address without having to make a new copy of the whole customer.