mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-03-03 00:09:19 +00:00
git-svn-id: https://svn.jboss.org/repos/hibernate/trunk/Hibernate3/doc@8370 1b8cb986-b30d-0410-93ca-fae66ebed9b2
348 lines
18 KiB
XML
348 lines
18 KiB
XML
<chapter id="architecture">
|
|
|
|
<title>Architecture</title>
|
|
|
|
<sect1 id="architecture-overview" revision="1">
|
|
<title>Overview</title>
|
|
|
|
<para>
|
|
A (very) high-level view of the Hibernate architecture:
|
|
</para>
|
|
|
|
<mediaobject>
|
|
<imageobject role="fo">
|
|
<imagedata fileref="images/overview.svg" format="SVG" align="center"/>
|
|
</imageobject>
|
|
<imageobject role="html">
|
|
<imagedata fileref="../shared/images/overview.gif" format="GIF" align="center"/>
|
|
</imageobject>
|
|
</mediaobject>
|
|
|
|
<para>
|
|
This diagram shows Hibernate using the database and configuration data to
|
|
provide persistence services (and persistent objects) to the application.
|
|
</para>
|
|
|
|
<para>
|
|
We would like to show a more detailed view of the runtime architecture.
|
|
Unfortunately, Hibernate is flexible and supports several approaches. We will
|
|
show the two extremes. The "lite" architecture has the application
|
|
provide its own JDBC connections and manage its own transactions. This approach
|
|
uses a minimal subset of Hibernate's APIs:
|
|
</para>
|
|
|
|
<mediaobject>
|
|
<imageobject role="fo">
|
|
<imagedata fileref="images/lite.svg" format="SVG" align="center"/>
|
|
</imageobject>
|
|
<imageobject role="html">
|
|
<imagedata fileref="../shared/images/lite.gif" format="GIF" align="center"/>
|
|
</imageobject>
|
|
</mediaobject>
|
|
|
|
<para>
|
|
The "full cream" architecture abstracts the application away from the
|
|
underlying JDBC/JTA APIs and lets Hibernate take care of the details.
|
|
</para>
|
|
|
|
<mediaobject>
|
|
<imageobject role="fo">
|
|
<imagedata fileref="images/full_cream.svg" format="SVG" align="center"/>
|
|
</imageobject>
|
|
<imageobject role="html">
|
|
<imagedata fileref="../shared/images/full_cream.gif" format="GIF" align="center"/>
|
|
</imageobject>
|
|
</mediaobject>
|
|
|
|
<para>
|
|
Heres some definitions of the objects in the diagrams:
|
|
|
|
<variablelist spacing="compact">
|
|
<varlistentry>
|
|
<term>SessionFactory (<literal>org.hibernate.SessionFactory</literal>)</term>
|
|
<listitem>
|
|
<para>
|
|
A threadsafe (immutable) cache of compiled mappings for a single database.
|
|
A factory for <literal>Session</literal> and a client of
|
|
<literal>ConnectionProvider</literal>. Might hold an optional (second-level)
|
|
cache of data that is reusable between transactions, at a
|
|
process- or cluster-level.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Session (<literal>org.hibernate.Session</literal>)</term>
|
|
<listitem>
|
|
<para>
|
|
A single-threaded, short-lived object representing a conversation between
|
|
the application and the persistent store. Wraps a JDBC connection. Factory
|
|
for <literal>Transaction</literal>. Holds a mandatory (first-level) cache
|
|
of persistent objects, used when navigating the object graph or looking up
|
|
objects by identifier.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Persistent objects and collections</term>
|
|
<listitem>
|
|
<para>
|
|
Short-lived, single threaded objects containing persistent state and business
|
|
function. These might be ordinary JavaBeans/POJOs, the only special thing about
|
|
them is that they are currently associated with (exactly one)
|
|
<literal>Session</literal>. As soon as the <literal>Session</literal> is closed,
|
|
they will be detached and free to use in any application layer (e.g. directly
|
|
as data transfer objects to and from presentation).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Transient and detached objects and collections</term>
|
|
<listitem>
|
|
<para>
|
|
Instances of persistent classes that are not currently associated with a
|
|
<literal>Session</literal>. They may have been instantiated by
|
|
the application and not (yet) persisted or they may have been instantiated by a
|
|
closed <literal>Session</literal>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Transaction (<literal>org.hibernate.Transaction</literal>)</term>
|
|
<listitem>
|
|
<para>
|
|
(Optional) A single-threaded, short-lived object used by the application to
|
|
specify atomic units of work. Abstracts application from underlying JDBC,
|
|
JTA or CORBA transaction. A <literal>Session</literal> might span several
|
|
<literal>Transaction</literal>s in some cases. However, transaction demarcation,
|
|
either using the underlying API or <literal>Transaction</literal>, is never
|
|
optional!
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>ConnectionProvider (<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
|
|
<listitem>
|
|
<para>
|
|
(Optional) A factory for (and pool of) JDBC connections. Abstracts application from
|
|
underlying <literal>Datasource</literal> or <literal>DriverManager</literal>.
|
|
Not exposed to application, but can be extended/implemented by the developer.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>TransactionFactory (<literal>org.hibernate.TransactionFactory</literal>)</term>
|
|
<listitem>
|
|
<para>
|
|
(Optional) A factory for <literal>Transaction</literal> instances. Not exposed to the
|
|
application, but can be extended/implemented by the developer.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><emphasis>Extension Interfaces</emphasis></term>
|
|
<listitem>
|
|
<para>
|
|
Hibernate offers many optional extension interfaces you can implement to customize
|
|
the behavior of your persistence layer. See the API documentation for details.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
|
|
<para>
|
|
Given a "lite" architecture, the application bypasses the
|
|
<literal>Transaction</literal>/<literal>TransactionFactory</literal> and/or
|
|
<literal>ConnectionProvider</literal> APIs to talk to JTA or JDBC directly.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="architecture-states" revision="1">
|
|
<title>Instance states</title>
|
|
<para>
|
|
An instance of a persistent classes may be in one of three different states,
|
|
which are defined with respect to a <emphasis>persistence context</emphasis>.
|
|
The Hibernate <literal>Session</literal> object is the persistence context:
|
|
</para>
|
|
|
|
<variablelist spacing="compact">
|
|
<varlistentry>
|
|
<term>transient</term>
|
|
<listitem>
|
|
<para>
|
|
The instance is not, and has never been associated with
|
|
any persistence context. It has no persistent identity
|
|
(primary key value).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>persistent</term>
|
|
<listitem>
|
|
<para>
|
|
The instance is currently associated with a persistence
|
|
context. It has a persistent identity (primary key value)
|
|
and, perhaps, a corresponding row in the database. For a
|
|
particular persistence context, Hibernate
|
|
<emphasis>guarantees</emphasis> that persistent identity
|
|
is equivalent to Java identity (in-memory location of the
|
|
object).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>detached</term>
|
|
<listitem>
|
|
<para>
|
|
The instance was once associated with a persistence
|
|
context, but that context was closed, or the instance
|
|
was serialized to another process. It has a persistent
|
|
identity and, perhaps, a corrsponding row in the database.
|
|
For detached instances, Hibernate makes no guarantees
|
|
about the relationship between persistent identity and
|
|
Java identity.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect1>
|
|
|
|
<sect1 id="architecture-jmx" revision="1">
|
|
<title>JMX Integration</title>
|
|
|
|
<para>
|
|
JMX is the J2EE standard for management of Java components. Hibernate may be managed via
|
|
a JMX standard service. We provide an MBean implementation in the distribution,
|
|
<literal>org.hibernate.jmx.HibernateService</literal>.
|
|
</para>
|
|
|
|
<para>
|
|
For an example how to deploy Hibernate as a JMX service on the JBoss Application Server,
|
|
please see the JBoss User Guide. On JBoss AS, you also get these benefits if you deploy
|
|
using JMX:
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>Session Management:</emphasis> The Hibernate <literal>Session</literal>'s lifecycle
|
|
can be automatically bound to the scope of a JTA transaction. This means you no
|
|
longer have to manually open and close the <literal>Session</literal>, this
|
|
becomes the job of a JBoss EJB interceptor. You also don't have to worry about
|
|
transaction demarcation in your code anymore (unless you'd like to write a portable
|
|
persistence layer of course, use the optional Hibernate <literal>Transaction</literal>
|
|
API for this). You call the <literal>HibernateContext</literal> to access a
|
|
<literal>Session</literal>.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>HAR deployment:</emphasis> Usually you deploy the Hibernate JMX service using a JBoss
|
|
service deployment descriptor (in an EAR and/or SAR file), it supports all the usual
|
|
configuration options of a Hibernate <literal>SessionFactory</literal>. However, you still
|
|
have to name all your mapping files in the deployment descriptor. If you decide to use
|
|
the optional HAR deployment, JBoss will automatically detect all mapping files in your
|
|
HAR file.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>
|
|
Consult the JBoss AS user guide for more information about these options.
|
|
</para>
|
|
|
|
<para>
|
|
Another feature available as a JMX service are runtime Hibernate statistics. See
|
|
<xref linkend="configuration-optional-statistics"/>.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="architecture-jca" revision="1">
|
|
<title>JCA Support</title>
|
|
<para>
|
|
Hibernate may also be configured as a JCA connector. Please see the website for more
|
|
details. Please note that Hibernate JCA support is still considered experimental.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="architecture-current-session" revision="1">
|
|
<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, helper classes such as <literal>HibernateUtil</literal>, 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, 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.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>
|
|
Both implementations provide a "one session - one database transaction" programming
|
|
model, also known and used as <emphasis>session-per-request</emphasis>. The beginning
|
|
and end of a Hibernate session is defined by the duration of a database transaction.
|
|
If you use programatic transaction demarcation (e.g. in pure J2SE or with
|
|
JTA/UserTransaction/BMT), you are adviced to use the Hibernate <literal>Transaction</literal>
|
|
API to hide the underlying transaction system from your code. If you execute in
|
|
an EJB container that supports CMT, transaction boundaries are defined declaratively
|
|
and you don't need any transaction or session demarcation operations in your code.
|
|
Refer to <xref linkend="transactions"/> for more information and code examples.
|
|
</para>
|
|
|
|
<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>
|
|
|