Hi Fabrizio,

I wrote most of the tutorial you cite two years ago, but from the discussions on the list got the impression that most people switched to the CHS (Cocoon, Hibernate, Swing). Thus it is interesting to see that someone is actually still using this technique. I do it still, as well, since it "works for me" for medium-sized projects. So let me comment on the issues you bring up:

However, for more complex scenarios which involve displaying a sequence of
forms to the user, this 'session-per-request' approach is cumbersome - as
whenever the Flowscript continuation is suspended/resumed, you have to
manually re-associate any detached objects to the new Hibernate session...
This is true, and sometimes unconvenient, e.g. when you have a complex form spanning multiple pages.
So I've taken a closer look on the long session / conversation approach
described by the Hibernate authors - although it is generally considered
an anti-pattern by most web frameworks, due to its wasteful memory
requirements and potential garbage collection issues.
This is not the only problem really, but I go into this in more detail below.
Correct me if I'm wrong, but all the objects which I fetch before a
continuation is suspended (and which I don't explicitly care to dispose
of!) just stay there, hogging memory ...until the user decides to resume
the continuation or until the continuation times out, right?
Exactly.
But is my reasoning above, that a 'Flowscript continuation is indeed a
long session', correct, or did I overlook something obvious?
This is precisely what flowscript continuations are doing. However, there is a tricky philosophical issue here. A Flowscript connection holds exactly the information that is necessary to continue program execution at the point it was interrupted by e.g. cocoon.sendPageAndWait(). This usually boils down to local and global variables. In fact, if you have a global variable in your flowscript, Cocoon will automatically create an HTTP session to store it in, even if its value is never accessed or modified. Otherwise, an HTTP session will only be created when you call sendPageAndWait() or something similar.

Of course, the global variables you are storing can also be "real" Java objects instead of trivial javascript variables containing just integers and strings. I used this, for example, in an online shop application where the shopping basket is a java.util.Vector containing objects which were initially fetched by Hibernate. This is when I first ran into the problem you described: After the first continuation, Hibernate would complain about accessing an object whose session had been closed. I actually solved this problem by copying the fetched objects to non-persistent instances.

In theory, it is of course also possible to store the Hibernate session itself in the HTTP session, or as a global variable in the flowscript. However, there are several reasons why I think this is a bad idea:

(1) Connection pooling. In my setup - which is also described in the wiki - Hibernate uses pooled connections. If a lot of sessions are opened and not closed properly, or by a timeout, I am not sure whether the underlying JDBC connection would be properly closed and returned to the pool. In any case, you will run out of connections faster than when returning each JDBC connection to the pool when the view was rendered. Actually, it is a classical and frustrating problem to run out of JDBC connections, and it is one of the main strengths of the OpenSessionInView design patterns that it gets rid of this issue.

(2) I think that it is against the philosophy of flowscript continuations to store objects which have side non-obvious side effects, such as keeping a JDBC connection open or needing an open Hibernate session to call the setter methods, across sessions.

(3) Most "write" operations should be wrapped in a JTA transaction to make sure that they are actually executed. Since these transactions are atomary, this might block other JTA transactions for a much too long time (although I am not 100% sure on this one)

(4) Architecture. I never felt good about using Hibernate directly in flowscript anyway, since it is supposed to be on the "M" (model) layer of the MVC pattern, while flowscript is IMHO on the C (control) layer. With the current setup in wiki, sessions are opened in flowscript, but closed in Java, which is ugly. I think that the way to go is the classical "DAO" (data access object) pattern, which should wrap calls to Hibernate - which brings you closer to what Spring is supposed to do, but of course you can implement DAO yourself without using Spring, which is what I do. In this setup, Hibernate sessions are openened and closed as needed in the Data Access Objects. In flowscript, you only interact with the data access objects. This makes it necessary to provide Hibernate with a different connection pool than Cocoon's, but that makes perfect sense to me since it decouples cocoon from all the database and hibernate stuff, thus leading to a "clean" MVC structure (apart from the OpenSessionInView filter, but this is a standard issue).

I hope to have enough time to document this setup in wiki soon, since I like it much more than the described one. However, I would also be glad to hear more from your experiences with the open session across continuations - it is certainly (to me) one of the more interesting aspects of Java web development that you have a variety of philosophies and approaches.

Apologies for the lengthy reply and best regards,
Johannes




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to