Many applications need to retrieve an object in one transaction, send it to
the UI layer for manipulation, then save the changes in a new transaction.
Applications that use this kind of approach in a high-concurrency environment
usually use versioned data to ensure isolation for the "long" unit of work.
Hibernate supports this model by providing for reattachment of detached
instances using the Session.update()
or Session.merge()
methods:
// in the first session
Cat cat = (Cat) firstSession.load(Cat.class, catId);
Cat potentialMate = new Cat();
firstSession.save(potentialMate);
// in a higher layer of the application
cat.setMate(potentialMate);
// later, in a new session
secondSession.update(cat); // update cat
secondSession.update(mate); // update mate
If the Cat
with identifier catId
had already been loaded by secondSession
when the application tried to reattach it, an
exception would have been thrown.
Use update()
if you are sure that the session does
not contain an already persistent instance with the same identifier, and merge()
if you want to merge your modifications at any time
without consideration of the state of the session. In other words, update()
is usually the first method you would call in a
fresh session, ensuring that reattachment of your detached instances is the
first operation that is executed.
The application should individually update()
detached instances reachable from the given detached instance if and only if it wants their state also updated. This
can be automated of course, using transitive
persistence, see Section 10.11, “Transitive persistence”.
The lock()
method also allows an application to
reassociate an object with a new session. However, the detached instance has to
be unmodified!
//just reassociate:
sess.lock(fritz, LockMode.NONE);
//do a version check, then reassociate:
sess.lock(izi, LockMode.READ);
//do a version check, using SELECT ... FOR UPDATE, then reassociate:
sess.lock(pk, LockMode.UPGRADE);
Note that lock()
can be used with various LockMode
s, see the API documentation and the chapter on
transaction handling for more information. Reattachment is not the only usecase
for lock()
.
Other models for long units of work are discussed in Section 11.3, “Optimistic concurrency
control”.