In the Hibernate 3.0 Docs Chapter 11 talks about this issue.
It also talks about Detached Objects, and Long Sessions. I am just a bit confused how hibernate implements the optimistic concurrency and what settings I need to set up to allow hibernate to handle my versioning.
So say, In a web app I am updating a users profile the same time someone else is updating the same user profile (2 different sessions). The object used to represent the data has become detached because it was just needed for the view.
I make my changes first and commit them. The second user finishes and tries to submit his changes. The way the concurrency works is just by throwing the staleobject exception? And hibernate knows it is stale through the versioning?
So to handle this exception, I could just alert the second user the data is old? So that essentially is how hibernate does concurrency?
And is this equivalent to using the automatic concurrency idiom, along with the detached object pattern?
And in theory I could be using automatic versioning with detached objects and have a long session open all at once (That would probably be bad code though).
And along those lines, what's the difference between caching an object in the SessionFactory, so all sessions are working with the same object?
Also, is there a best practice or pattern to allow hibernate to handle concurrency among multiple servers.
Sorry, for all this just jumbled together. And thanks for your assistance in advance!
I am still having issues getting hibernate to use versioning.
This is my mapping file:
Is there anything else I have to do? To test, I created a jsp that just updates the title. I open up 2 browsers and grab the object in each. Then I edit one, and comitt the changes. The version number is changing in the DB. Then I update the other, but no stale object exception is thrown.
Any ideas? [ June 26, 2006: Message edited by: Jonathan Huang ]
What is the final version number? Is is one or two more than it was to start with?
Joined: Jun 23, 2006
It is incrimented once.
So I start with version 0.
Make a change, it is now version 1. The old object is version 0 when I make the changes. And where the StaleObjectException should change.
There are 2 hibernate queries going through at each form submit. 1) Update, 2) Select (to redisplay the information).
I tried using optimistic-lock="all". That didn't work as all. That made 3 queries: 1) select - I believe this one is the version check, where an exception is not thrown. 2) update - the update 3) select - the select to redisplay.
I am going to look into my error handling and make sure error logs are properly being caught and thrown.
Looking at you code you do seem to be getting the object in the same transaction that you update it. I wouldn't expect a StaleUpdateException in that case, though I would expect the version number to be incremented twice.
I am not familiar with hibernateSync, can you tell me is the session shared between the two requests? Or does each request have its own session? When is the session actually flushed (or closed)?
Joined: Jun 23, 2006
it must be in the same transaction, I guess, since no stale object is being thrown. I just don't understand why.
From my looking thorugh Hibernate Sync's generated code. Any time a load/save/update is called, the transaction is opened, from the current session, the action done, then everything closed properly.
Although now looking through the get and load generated functions, the session is never closed and there is no transaction. it's just session.get(Class, key)
I'll have to edit the code and test some new things out.
The main problem was that HibernateSync does a funny closing of sessions when lazy initialization is active. Once I started understanding the generated code a little more I was able to make proper test cases and close my sessions properly.
On a side note, do you know of any references in creating your own transaction.manager_lookup_class?