Author: steve.ebersole(a)jboss.com
Date: 2009-06-10 14:46:26 -0400 (Wed, 10 Jun 2009)
New Revision: 16752
Added:
core/branches/Branch_3_3/documentation/manual/src/main/docbook/en-US/content/portability.xml
Log:
minor changes; added biblio references for JPwH
Added:
core/branches/Branch_3_3/documentation/manual/src/main/docbook/en-US/content/portability.xml
===================================================================
---
core/branches/Branch_3_3/documentation/manual/src/main/docbook/en-US/content/portability.xml
(rev 0)
+++
core/branches/Branch_3_3/documentation/manual/src/main/docbook/en-US/content/portability.xml 2009-06-10
18:46:26 UTC (rev 16752)
@@ -0,0 +1,204 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<chapter id="portability">
+ <title>Database Portability Considerations</title>
+
+ <sect1 id="portability-basics">
+ <title>Portability Basics</title>
+
+ <para>
+ One of the selling points of Hibernate (and really Object/Relational Mapping
as a whole) is
+ the notion of database portability. This could mean an internal IT user
migrating from one
+ database vendor to another, or it could mean a framework or deployable
application consuming
+ Hibernate to simultaneously target multiple database products by their users.
Regardless of
+ the exact scenario, the basic idea is that you want Hibernate to help you run
against any number
+ of databases without changes to your code, and ideally without any changes to
the mapping metadata.
+ </para>
+ </sect1>
+
+ <sect1 id="portability-dialect">
+ <title>Dialect</title>
+
+ <para>
+ The first line of portability for Hibernate is the dialect, which is a
specialization of the
+ <classname>org.hibernate.dialect.Dialect</classname> contract. A
dialect encapsulates all
+ the differences in how Hibernate must communicate with a particular database
to accomplish some
+ task like getting a sequence value or structuring a SELECT query. Hibernate
bundles a wide range
+ of dialects for many of the most popular databases. If you find that your
particular database is
+ not among them, it is not terribly difficult to write your own.
+ </para>
+ </sect1>
+
+ <sect1 id="portability-dialectresolver">
+ <title>Dialect resolution</title>
+
+ <para>
+ Originally, Hibernate would always require that users specify which dialect
to use. In the case
+ of users looking to simultaneously target multiple databases with their build
that was problematic.
+ Generally this required their users to configure the Hibernate dialect or
defining their own method
+ of setting that value.
+ </para>
+
+ <para>
+ Starting with version 3.2, Hibernate introduced the notion of automatically
detecting the dialect
+ to use based on the
<interfacename>java.sql.DatabaseMetaData</interfacename> obtained from a
+ <interfacename>java.sql.Connection</interfacename> to that
database. This was much better, expect
+ that this resolution was limited to databases Hibernate know about ahead of
time and was in no way
+ configurable or overrideable.
+ </para>
+
+ <para>
+ Starting with version 3.3, Hibernate has a fare more powerful way to
automatically determine
+ which dialect to should be used by relying on a series of delegates which
implement the
+
<interfacename>org.hibernate.dialect.resolver.DialectResolver</interfacename>
which defines only a
+ single method:<programlisting><![CDATA[public Dialect
resolveDialect(DatabaseMetaData metaData) throws
JDBCConnectionException]]></programlisting>.
+ The basic contract here is that if the resolver 'understands' the
given database metadata then
+ it returns the corresponding Dialect; if not it returns null and the process
continues to the next
+ resolver. The signature also identifies
<exceptionname>org.hibernate.exception.JDBCConnectionException</exceptionname>
+ as possibly being thrown. A JDBCConnectionException here is interpreted to
imply a "non transient"
+ (aka non-recoverable) connection problem and is used to indicate an immediate
stop to resolution
+ attempts. All other exceptions result in a warning and continuing on to the
next resolver.
+ </para>
+
+ <para>
+ The cool part about these resolvers is that users can also register their own
custom resolvers
+ which will be processed ahead of the built-in Hibernate ones. This might be
useful in a number of
+ different situations: it allows easy integration for auto-detection of
dialects beyond those
+ shipped with HIbernate itself; it allows you to specify to use a custom
dialect when a particular
+ database is recognized; etc. To register one or more resolvers, simply
specify them (seperated by
+ commas, tabs or spaces) using the 'hibernate.dialect_resolvers'
configuration setting (see the
+ <constant>DIALECT_RESOLVERS</constant> constant on
+
<ooclass><package>org.hibernate.cfg</package><classname>Environment</classname></ooclass>).
+ </para>
+ </sect1>
+
+ <sect1 id="portability-idgen">
+ <title>Identifier generation</title>
+
+ <para>
+ When considering portability between databases, another important decision is
selecting the
+ identifier generation stratagy you want to use. Originally Hibernate
provided the
+ <emphasis>native</emphasis> generator for this purpose, which was
intended to select between
+ a <emphasis>sequence</emphasis>,
<emphasis>identity</emphasis>, or <emphasis>table</emphasis>
+ strategy depending on the capability of the underlying database. However, an
insidious implication
+ of this approach comes about when targtetting some databases which support
<emphasis>identity</emphasis>
+ generation and some which do not. <emphasis>identity</emphasis>
generation relies on the SQL
+ definition of an IDENTITY (or auto-increment) column to manage the identifier
value; it is what is
+ known as a post-insert generation strategy becauase the insert must actually
happen before we can
+ know the identifier value. Because Hibernate relies on this identifier value
to uniquely reference
+ entities within a persistence context it must then issue the insert
+ immediately when the users requests the entitiy be associated with the
session (like via
+ save() e.g.) regardless of current transactional semantics.
+
+ <note>
+ <para>
+ Hibernate was changed slightly once the implication of this was
better understood so that
+ the insert is delayed in cases where that is feasible.
+ </para>
+ </note>
+
+ The underlying issue is that the actual semanctics of the application itself
changes in these cases.
+ </para>
+
+ <para>
+ Starting with version 3.2.3, Hibernate comes with a set of
+ <ulink
url="http://in.relation.to/2082.lace">enhanced</ulink> identifier
generators targetting
+ portability in a much different way.
+ <note>
+ <para>
+ There are specifically 2 bundled
<emphasis>enhanced</emphasis>generators:
+ <itemizedlist>
+ <listitem>
+ <para>
+
<classname>org.hibernate.id.enhanced.SequenceStyleGenerator</classname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
<classname>org.hibernate.id.enhanced.TableGenerator</classname>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </note>
+ The idea behind these generators is to port the actual semantics of the
identifer value
+ generation to the different databases. For example, the
+
<classname>org.hibernate.id.enhanced.SequenceStyleGenerator</classname> mimics
the behavior of
+ a sequence on databases which do not support sequences by using a table.
+ </para>
+ </sect1>
+
+ <sect1 id="portability-functions">
+ <title>Database functions</title>
+
+ <warning>
+ <para>
+ This is an area in Hibernate in need of improvement. In terms of
portability concerns,
+ this function handling currently works pretty well from HQL; however, it
is quite lacking
+ in all other aspects.
+ </para>
+ </warning>
+
+ <para>
+ SQL functions can be referenced in many ways by users. However, not all
databases
+ support the same set of functions. Hibernate, provides a means of mapping a
+ <emphasis>logical</emphasis> function name to a a delegate which
knows how to render
+ that particular function, perhaps even using a totally different physical
function call.
+ <important>
+ <para>
+ Technically this function registration is handled through the
+
<classname>org.hibernate.dialect.function.SQLFunctionRegistry</classname>
class
+ which is intended to allow users to provide custom function
definitions without
+ having to provide a custom dialect. This specific behavior is not
fully completed
+ as of yet.
+ </para>
+ <para>
+ It is sort of implemented such that users can programatically
register functions
+ with the
<classname>org.hibernate.cfg.Configuration</classname> and those functions
+ will be recognized for HQL.
+ </para>
+ </important>
+ </para>
+ </sect1>
+
+ <sect1 id="portability-types">
+ <title>Type mappings</title>
+
+ <para>
+ This section scheduled for completion at a later date...
+ </para>
+
+ <!--
+ todo :
+ <sect2 id="portability-types-lobs">
+ <title>BLOB/CLOB mappings</title>
+ </sect2>
+
+ <sect2 id="portability-types-bool">
+ <title>Boolean mappings</title>
+ </sect2>
+ -->
+ </sect1>
+</chapter>
\ No newline at end of file
Show replies by date