added section about new CurrectSessionContext capabilities;

modified sections currently talking about SF.getCurrentSession()


git-svn-id: https://svn.jboss.org/repos/hibernate/trunk/Hibernate3/doc@8312 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2005-10-03 17:22:29 +00:00
parent 6379f86397
commit c7878b776b
3 changed files with 91 additions and 18 deletions

View File

@ -265,5 +265,77 @@
</para>
</sect1>
<sect1 id="architecture-current-session">
<title>Contextual Sessions</title>
<para>
Most applications using Hibernate need some form of "contextual" sessions, where a given
session is in effect throughout the scope of a given context. However, across applications
the definition of what constitutes a context is typically different; and different contexts
define different scopes to the notion of current. Applications using Hibernate prior
to version 3.0 tended to utilize either home-grown <literal>ThreadLocal</literal>-based
contextual sessions, or utilized third-party frameworks (such as Spring or Pico) which
provided proxy/interception-based contextual sessions.
</para>
<para>
Starting with version 3.0.1, Hibernate added the <literal>SessionFactory.getCurrentSession()</literal>
method. Initially, this assumed usage of <literal>JTA</literal> transactions, where the
<literal>JTA</literal> transaction defined both the scope and context of a current session.
The Hibernate team maintains that, given the maturity of the numerous stand-alone
<literal>JTA TransactionManager</literal> implementations out there, most (if not all)
applications should be using <literal>JTA</literal> transaction management whether or not
they are deployed into a <literal>J2EE</literal> container. Based on that, the
<literal>JTA</literal>-based contextual sessions is all you should ever need to use.
</para>
<para>
However, we recognize that with the large amounts of FUD out there regarding
<literal>JTA</literal>, such a shift in thinking may be a long time coming to
fruition. Thus, as of version 3.1, the processing behind
<literal>SessionFactory.getCurrentSession()</literal> is now pluggable. To that
end, a new extension interface (<literal>org.hibernate.context.CurrentSessionContext</literal>)
and a new configuration parameter (<literal>hibernate.current_session_context_class</literal>)
have been added to allow pluggability of the scope and context of defining current sessions.
</para>
<para>
See the javadocs for the <literal>org.hibernate.context.CurrentSessionContext</literal>
interface for a detailed discussion of its contract. It defines a single method,
<literal>currentSession()</literal>, by which the implementation is responsible for
tracking the current contextual session. Out-of-the-box, Hibernate comes with two
implementations of this interface.
</para>
<itemizedlist>
<listitem>
<para>
<literal>org.hibernate.context.JTASessionContext</literal> - current sessions
are tracked and scoped by a <literal>JTA</literal> transaction. The processing
here is exactly the same as in the older JTA-only approach. See the javadocs
for details.
</para>
</listitem>
<listitem>
<para>
<literal>org.hibernate.context.ThreadLocalSessionContext</literal> - current
sessions are tracked by thread of execution. Again, see the javadocs for details.
However, it is important to point out that when using threads as the context
mechanism, there is no clearly defined notion of scoping. Threads, unlike
<literal>JTA</literal> transactions, do not emit completion notifications; and
even worse is the fact that many, many environments actually pool and re-use
threads. Thus user of the <literal>ThreadLocalSessionContext</literal> are
expected to manually call the static bind and unbind methods to manually
demarcate context boundaries.
</para>
</listitem>
</itemizedlist>
<para>
The <literal>hibernate.current_session_context_class</literal> configuration parameter
defines which <literal>org.hibernate.context.CurrentSessionContext</literal> implementation
should be used. Note that for backwards compatibility, if this config param is not set
but a <literal>org.hibernate.transaction.TransactionManagerLookup</literal> is configured,
Hibernate will use the <literal>org.hibernate.context.JTASessionContext</literal>.
Typically, the value of this parameter would just name the implementation class to
use; for the two out-of-the-box implementations, however, there are two corresponding
short names, "jta" and "thread".
</para>
</sect1>
</chapter>

View File

@ -1602,7 +1602,7 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
</sect2>
<sect2 id="configuration-j2ee-currentsession" revision="2">
<sect2 id="configuration-j2ee-currentsession" revision="3">
<title>Automatic JTA and Session binding</title>
<para>
@ -1614,24 +1614,24 @@ hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
</para>
<para>
Instead of rolling your own <literal>ThreadLocal</literal> utility, use the
<literal>getCurrentSession()</literal> method on the <literal>SessionFactory</literal>
to obtain a Hibernate <literal>Session</literal>. If there is no Hibernate
<literal>Session</literal> in current JTA transaction, one will be started and
assigned. Both the <literal>hibernate.transaction.flush_before_completion</literal>
and <literal>hibernate.transaction.auto_close_session</literal> configuration option,
will be set automatically for every <literal>Session</literal> you retrieve with
<literal>getCurrentSession()</literal>, so they will also be flushed and closed
automatically when the container ends the JTA transactions. This is an alternative
to <literal>ThreadLocal</literal> management. The <literal>HibernateUtil</literal>
class you can find with the <emphasis>CaveatEmptor</emphasis> application can
actually switch between both strategies automatically, hence, keeps your code
portable between transaction-local, BMT, and CMT environments.
Instead of rolling your own <literal>ThreadLocal</literal> utility, we also recommend
use of the <literal>getCurrentSession()</literal> method on <literal>SessionFactory</literal>
to obtain a Hibernate <literal>Session</literal>. See the discussion of
<xref linkend="architecture-current-session">current sessions</xref>. Using the
<literal>"jta"</literal> session context, if there is no Hibernate
<literal>Session</literal> associated with the current JTA transaction, one will
be started and associated with that JTA transaction. The <literal>Session</literal>s
retrieved via <literal>getCurrentSession()</literal> in <literal>"jta"</literal> context
will be set to automatically flush before the transaction completes, close
after the transaction completes, and aggressively release JDBC connections
after each statement. This allows the <literal>Session</literal>s to
be managed by the lifecycle of the JTA transaction to which it is associated,
keeping user code clean of such management concerns.
</para>
<para>
If you, for example, use the DAO design pattern to write your persistence layer,
all DAO's lookup the <literal>SessionFactory</literal> when needed and open the
all DAO's lookup the <literal>SessionFactory</literal> when needed and retrieve the
"current" Session. There is no need to pass instances of <literal>SessionFactory</literal>
or <literal>Session</literal> around between controlling code and DAO code.
</para>

View File

@ -454,7 +454,7 @@ finally {
</sect2>
<sect2 id="transactions-demarcation-jta">
<sect2 id="transactions-demarcation-jta" revision="1">
<title>Using JTA</title>
<para>
@ -533,13 +533,14 @@ finally {
</para>
<para>
If you work in a CMT environment, and use automatic flushing and closing of the session, you
If you work in a JTA environment, and use automatic flushing and closing of the session, you
might also want to use the same session in different parts of your code. Typically, in a non-managed
environment you would use a <literal>ThreadLocal</literal> variable to hold the session, but a
single EJB request might execute in different threads (e.g. session bean calling another session bean).
If you don't want to bother passing your <literal>Session</literal> instance around, the
<literal>SessionFactory</literal> provides the <literal>getCurrentSession()</literal>
method, which returns a session that is bound to the JTA transaction context. This is the
method, which returns a session that is bound to the JTA transaction context (see discussion of
<xref linkend="architecture-current-session">current sessions</xref>). This is the
easiest way to integrate Hibernate into an application! The "current" session always has
auto-flush, auto-close and auto-connection-release enabled (regardless of the above property
settings). Our session/transaction management idiom is reduced to this: