cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ugo Cei <u....@cbim.it>
Subject Re: Hibernate sessions (was Re: [vote results] FOM)
Date Wed, 18 Jun 2003 13:14:49 GMT
Jeremy Quinn wrote:
> Because (I just realised) the Session has to be thrown away if there is 
> any kind of Hibernate Exception, I was beginning to realise the only way 
> of handling that safely was to wrap each call to Hibernate with a new 
> Session.

Not every call to Hibernate but every HTTP request processing, which 
might involve more than one call.

> The problem I still have to face is that I have to use 'lazy 
> initialisation' as I am editing trees of objects with child/parent 
> relationships, and I don't want the whole database loaded at once ;)
> The problem is that if you try to access a Bean property that is not 
> initialised (because it is lazy), while the Session is closed, you run 
> the risk of getting a LazyInitializationException.
> 
> The obvious time to close the Session is when you are ready to send a 
> page, but it is after you have sent the page (from FlowScript) that 
> access to the Bean properties from JXForm takes place.

Looks like you haven't read the URL I mentioned very carefully ;-).

The servlet filter you install (lazily) opens a session *before* letting 
Cocoon process the request. Then closes the session *after* the response 
has been sent. And all of this happens transparently, no need to wrap 
your code with try { ... } finally { session.close(); }.

When the view is realized, the session is still open, but it closes 
automatically after the last byte of the response has been sent to the 
client. Thus, there are no problems with lazy initialization.

This also implies that the session that is stored in the continuation is 
closed by the time the continuation is invoked again, and you need to 
get a new session, if you need it. See this pseudocode for an example:

function editItem(form, id) {
   var session = Persistence.getSession();
   var model = session.load(id);
   form.setModel(model);
   form.sendView("editPage");
   session = Persistence.getSession(); // this gets the new session
   session.saveOrUpdate(model);
   form.finish("editOK");
}

There are some cases where this might not work, like for instance if you 
want to use pessimistic locking. In this case, you should override this 
pattern by not calling Persistence.getSession() (and since the session 
is lazily initialized, this will avoid opening a session altogether), 
directly opening a new Hibernate session yourself and locking your model 
for updates with LockMode.UPGRADE. Of course, you run the risk of having 
a record locked indefinitely, and you should take care to release the 
lock when the continuation expires.

This is why I avoid pessimistic locking in web applications like the 
plague ;-).

	Ugo

-- 
Ugo Cei - Consorzio di Bioingegneria e Informatica Medica
P.le Volontari del Sangue, 2 - 27100 Pavia - Italy
Phone: +39.0382.525100 - E-mail: u.cei@cbim.it


Mime
View raw message