Hi Fabrizio, Johannes,
Very interesting mails you have made as I am using the same tutorial
during my work experience.
Being a newbie, I struggled quite a time on the model and finally used
Generic DAO like described here : http://www.hibernate.org/328.html
For sure having the FlowScript to open Hibernate Sessions is messy in
the MVC pattern, in your implementation are you using some
HibernateUtil-like class ?
I don't know your DAO implementation, but is having every DAO wrapping
the calls to Hibernate (i.e. Session handling) some sort of violation of
Inversion of Control pattern ?
- Not very sure that this question is justified !
Anyway thanks for your tutorial which helped me ALOT :)
Baptiste
Johannes Textor a écrit :
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]