> hhmmmmmmm .... damn this is all coming back to haunt .....

Sorry to rehash - I hadn't seen the previous discussion.  I'll check out the
archives to catch up, although I haven't yet done so in the response below.

> Lets state the problem carefully:
>
> What API allows the user to END a Session and
>
> (1) is easy to use and understand for new users,
> (2) has methods with clear semantics,
> (3) supports the various different possible styles of connection +
> transaction management eg. application server datasource + JTA,
> DriverManager + Connection.commit(), long transactions,
> (4) comforms to the philosophy that Hibernate is a thin wrapper
> around JDBC that exposes all underlying JDBC functionality to
> the application. (A wrapper with "windows"?)

I agree with all of that.  I'm proposing two additional requirements, one of
which I stated explicitly and one of which I didn't (but should have).  The
one I stated explicitly was:

> application code could switch the underlying transaction
> handling mechanism without changing the client code

Aside from the convenience of this, I think that the current design with
session.connection().xxx encourages users to depend on direct access to the
Connection, and doesn't provide an alternative.  In a sense, this leads
users down the wrong path - Hibernate abstracts all sorts of things but then
just exposes the connection and encourages its use.  I'm all for the idea of
"a wrapper with windows", but I'm also suggesting that it shouldn't be
necessary to use those windows.  It should be an option for those who want
it.

My second requirement comes from never having been a fan of the JDBC
transaction API, and its reliance on toggling autoCommit to begin and end
transactions.  This is unintuitive, doesn't "say what it means", and can
have bad consequences in the case of mistakes.  For example, forgetting to
setAutoCommit(true) at the end of a transaction results in all subsequent
requests on that connection being lumped into a single transaction, with
potentially horrible effects on concurrency.

I'm suggesting that a very thin wrapper here would be beneficial in general,
and I think it's appropriate for Hibernate to offer this as an optional
alternative, to encourage sensible transaction usage that reads well in the
application code, guards against certain kinds of errors, and corrects the
egregious mistakes that Sun made. ;)

If the above two additional requirements are met, I'm not as concerned about
the exact form this API takes.  OTOH, if everyone thinks I've been smoking
the $2 crack, I'll stick to using my own wrapper to get the functionality I
want.  What prompted me to start this thread was the questions that have
arisen about what Sessions are, and the attempt to clarify them in
documentation.

I think part of the problem is that the relationship between a Session and a
transaction isn't as clear as it might be, and this is at least partly
because the separation between the two is currently implemented by saying
"here's the connection, you're on your own with transactions".  I imagine
this is likely to encourage the tendency of users to think of a session as
being like a connection, which you can use repeatedly for multiple
transactions.

I think that making it unnecessary to directly access the connection would
be of general benefit to Hibernate users, and as a side benefit, may be less
likely to result in confusion, although obviously that's just a guess.  It
would still be necessary to make it clear, for example, that multiple
transactions shouldn't be executed on a single session.

I suppose commitTransaction() and rollbackTransaction() could also simply
close the connection - more on this below.

> When we had this discussion earlier, Brad Clow commented that one
> thing that was so confusing was that we were overloading the word
> "commit" to mean something other than committing a transaction.
> I agreed at the time, and still agree. If we do something like
> you are suggesting, we should not use the words "commit", "begin"
> "rollback" or "transaction" anywhere on the Session interface.

That was why I suggested method names like "commitTransaction".  My intent
was to clearly delineate between operations on the Hibernate Session, and
the conceptual/database transaction.

I was also trying to stick more closely to the current API's approach, and
basically suggesting that session.connection().commit() could simply be
(optionally) replaced by session.commitTransaction(), which would buy some
additional abstraction and thus flexibility.  My suggestion actually doesn't
change the current API all that much, and of course the existing API could
still be used as is, i.e. it's a backwards-compatible addition.

> public interface Session {
>   .....
>   public void end() throws ....;     //commit, close
>   public void cancel() throws ....;  //rollback, close
>   public void pause() throws ....;   //commit, disconnect
>   public void resume() throws .....; //reconnect
> }

This would satisfy my concerns above in terms of its functionality.  I have
two further observations:

1.  The begin/commit/rollback idiom is pretty well known and understood.
Essentially making up new words for these doesn't necessarily help new
users.

2.  I do see some benefit to separating the transaction functionality from
the session.  For example (and perhaps I just need more info here): what
about the case where a session will be "read-only", so that an explicit
overall transaction isn't needed, i.e. equivalent to JDBC
setAutoCommit(true)?  If an overall transaction is implicitly created by
Hibernate, it could reduce concurrency unnecessarily.  This was one reason
why I thought it might be a good idea to separate out the transaction calls
from the session open/close.  A readonly session could simply omit the
transaction calls, and perhaps include an initial call to suspendFlushes(),
for example.  I think this might be simpler than adding features to the
above API to support this case.

> I'm also not keen on changing the cirrus.hibernate.Session interface again
> at this stage. It might be preferable to develop this API (ie. the new
> Session and SessionFactory interfaces) in a seperate package. Say,
> cirrus.hibernate.4dummies or something. ;-> The new functionality could be
> implemented either on the existing cirrus.hibernate.impl classes or as
> wrapper classes that delegate to cirrus.hibernate.SessionFactory and
> cirrus.hibernate.Session.

I'm sensitive to this concern.  Again, that was a reason I proposed adding
xxxTransaction() to Session, since it wouldn't break existing code, and it
could be an optional mechanism.  If the other approach is decided on, making
a Session the same as a transaction, perhaps an alternative to Session would
be needed.

I'm being very outspoken for a brand new Hibernate user working on his first
application with it.  All Gavin's fault for encouraging me. :)  If I'm
missing something or am wrong about this, please apply cluestick to my
noggin with appropriate force.  But even if my conclusions aren't palatable,
I think at least the concern about wrapping connections has validity, and
I'd be interested in figuring out (and working on) a sufficiently general
way to address that.

Anton


_______________________________________________________________

Hundreds of nodes, one monster rendering program.
Now that’s a super model! Visit http://clustering.foundries.sf.net/
_______________________________________________
Hibernate-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/hibernate-devel

Reply via email to