Author: steve.ebersole(a)jboss.com
Date: 2007-10-09 14:28:36 -0400 (Tue, 09 Oct 2007)
New Revision: 14074
Added:
core/trunk/documentation/manual/fr-FR/src/main/docbook/Hibernate_Reference.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/architecture.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/association_mapping.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/basic_mapping.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/batch.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/best_practices.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/collection_mapping.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/component_mapping.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/configuration.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/events.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_mappings.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_parentchild.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_weblog.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/filters.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/inheritance_mapping.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/performance.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/persistent_classes.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/preface.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_criteria.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_hql.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_sql.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/session_api.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/toolset_guide.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/transactions.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/tutorial.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/xml.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/AuthorWork.png
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/AuthorWork.zargo
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/CustomerOrderProduct.png
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/CustomerOrderProduct.zargo
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/EmployerEmployee.png
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/EmployerEmployee.zargo
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.png
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.svg
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/hibernate_logo_a.png
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.png
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.svg
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.png
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.svg
core/trunk/documentation/manual/fr-FR/src/main/docbook/legal_notice.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/translators.xml
Removed:
core/trunk/documentation/manual/fr-FR/src/main/docbook/master.xml
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/
core/trunk/documentation/manual/fr-FR/src/main/resources/
Log:
new docbook layout (prep for translations migration to PO)
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/Hibernate_Reference.xml
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/Hibernate_Reference.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/Hibernate_Reference.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,72 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+ <!ENTITY versionNumber "3.3.0.alpha1">
+ <!ENTITY copyrightYear "2004">
+ <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
+]>
+
+<book>
+
+ <bookinfo>
+ <title>HIBERNATE - Persistance relationnelle en Java
standard</title>
+ <subtitle>Documentation de r�f�rence d'Hibernate</subtitle>
+ <releaseinfo>&versionNumber;</releaseinfo>
+ <productnumber>&versionNumber;</productnumber>
+ <issuenum>1</issuenum>
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="images/hibernate_logo_a.png"
align="center" />
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="images/hibernate_logo_a.png"
depth="3cm" />
+ </imageobject>
+ </mediaobject>
+ <copyright>
+ <year>©rightYear;</year>
+ <holder>©rightHolder;</holder>
+ </copyright>
+ <xi:include href="translators.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="legal_notice.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </bookinfo>
+
+ <toc/>
+
+ <xi:include href="content/preface.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/tutorial.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/architecture.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/configuration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/persistent_classes.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/basic_mapping.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/collection_mapping.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/association_mapping.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/component_mapping.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/inheritance_mapping.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/session_api.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/transactions.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/events.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/batch.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/query_hql.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_criteria.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/query_sql.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/filters.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/xml.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/performance.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/toolset_guide.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/example_parentchild.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_weblog.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="content/example_mappings.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+ <xi:include href="content/best_practices.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
+
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/architecture.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/architecture.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/architecture.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/architecture.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<chapter id="architecture">
+
+ <title>Architecture</title>
+
+ <sect1 id="architecture-overview" revision="1">
+ <title>G�n�ralit�s</title>
+
+ <para>
+ Voici une vue (tr�s) haut niveau de l'architecture d'Hibernate :
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/overview.svg"
format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/overview.gif"
format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ Ce diagramme montre Hibernate utilisant une base de donn�es et des donn�es
+ de configuration pour fournir un service de persistance (et des objets
+ persistants) � l'application.
+ </para>
+
+ <para>
+ Nous aimerions d�crire une vue plus d�taill�e de l'architecture.
Malheureusement,
+ Hibernate est flexible et supporte diff�rentes approches. Nous allons en
+ montrer les deux extr�mes. L'architecture l�g�re laisse l'application
fournir
+ ses propres connexions JDBC et g�rer ses propres transactions. Cette
approche
+ utilise le minimum des APIs Hibernate :
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/lite.svg"
format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/lite.gif"
format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ L'architecture la plus compl�te abstrait l'application des APIs
JDBC/JTA
+ sous-jacentes et laisse Hibernate s'occuper des d�tails.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/full_cream.svg"
format="SVG" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/full_cream.gif"
format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ Voici quelques d�finitions des objets des diagrammes :
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>SessionFactory
(<literal>org.hibernate.SessionFactory</literal>)</term>
+ <listitem>
+ <para>
+ Un cache threadsafe (immuable) des mappings vers une (et une
seule) base
+ de donn�es. Une factory (fabrique) de
<literal>Session</literal> et un client
+ de <literal>ConnectionProvider</literal>. Peut
contenir un cache optionnel de
+ donn�es (de second niveau) qui est r�utilisable entre les
diff�rentes transactions
+ que cela soit au sein du m�me processus (JVLM) ou par
plusieurs n�uds d'un cluster.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Session
(<literal>org.hibernate.Session</literal>)</term>
+ <listitem>
+ <para>
+ Un objet mono-thread�, � dur�e de vie courte, qui repr�sente
une conversation
+ entre l'application et l'entrep�t de persistance.
Encapsule une connexion JDBC.
+ Factory (fabrique) des objets
<literal>Transaction</literal>. Contient un cache
+ (de premier niveau) des objets persistants, ce cache est
obligatoire. Il est
+ utilis� lors de la navigation dans le graphe d'objets ou
lors de la r�cup�ration
+ d'objets par leur identifiant.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Objets et Collections persistants</term>
+ <listitem>
+ <para>
+ Objets mono-thread�s � vie courte contenant l'�tat de
persistance
+ et la fonction m�tier. Ceux-ci sont en g�n�ral les objets de
type JavaBean
+ (ou POJOs) ; la seule particularit� est qu'ils sont
associ�s avec une (et
+ une seule) <literal>Session</literal>. D�s que la
<literal>Session</literal>
+ est ferm�e, ils seront d�tach�s et libres d'�tre utilis�s
par n'importe laquelle
+ des couches de l'application (ie. de et vers la
pr�sentation en tant que Data
+ Transfer Objects - DTO : objet de transfert de donn�es).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Objets et collections transients</term>
+ <listitem>
+ <para>
+ Instances de classes persistantes qui ne sont actuellement
pas associ�es �
+ une <literal>Session</literal>. Elles ont pu �tre
instanci�es par l'application
+ et ne pas avoir (encore) �t� persist�es ou elle ont pu �tre
instanci�es par
+ une <literal>Session</literal> ferm�e.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Transaction
(<literal>org.hibernate.Transaction</literal>)</term>
+ <listitem>
+ <para>
+ (Optionnel) Un objet mono-thread� � vie courte utilis� par
l'application
+ pour d�finir une unit� de travail atomique. Abstrait
l'application des
+ transactions sous-jacentes qu'elles soient JDBC, JTA ou
CORBA. Une
+ <literal>Session</literal> peut fournir plusieurs
<literal>Transaction</literal>s
+ dans certains cas. Toutefois, la d�limitation des
transactions, via l'API d'Hibernate
+ ou par la <literal>Transaction</literal>
sous-jacente, n'est jamais optionnelle!
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ConnectionProvider
(<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
+ <listitem>
+ <para>
+ (Optionnel) Une fabrique de (pool de) connexions JDBC.
Abstrait l'application
+ de la <literal>Datasource</literal> ou du
<literal>DriverManager</literal> sous-jacent.
+ Non expos� � l'application, mais peut �tre
�tendu/impl�ment� par le d�veloppeur.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>TransactionFactory
(<literal>org.hibernate.TransactionFactory</literal>)</term>
+ <listitem>
+ <para>
+ (Optionnel) Une fabrique d'instances de
<literal>Transaction</literal>. Non
+ expos� � l'application, mais peut �tre �tendu/impl�ment�
par le d�veloppeur.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>Interfaces
d'extension</emphasis></term>
+ <listitem>
+ <para>
+ Hibernate fournit de nombreuses interfaces d'extensions
optionnelles que
+ vous pouvez impl�menter pour personnaliser le comportement de
votre couche de persistance.
+ Reportez vous � la documentation de l'API pour plus de
d�tails.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Dans une architecture l�g�re, l'application n'aura pas � utiliser les
APIs
+
<literal>Transaction</literal>/<literal>TransactionFactory</literal>
+ et/ou n'utilisera pas les APIs
<literal>ConnectionProvider</literal>
+ pour utiliser JTA ou JDBC.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-states" revision="1">
+ <title>Etats des instances</title>
+ <para>
+ Une instance d'une classe persistante peut �tre dans l'un des trois
�tats suivants,
+ d�finis par rapport � un <emphasis>contexte de
persistance</emphasis>.
+ L'objet <literal>Session</literal> d'hibernate correspond
� ce concept de
+ contexte de persistance :
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>passager (transient)</term>
+ <listitem>
+ <para>
+ L'instance n'est pas et n'a jamais �t� associ�e � un
contexte
+ de persistance. Elle ne poss�de pas d'identit� persistante
(valeur de cl� primaire)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>persistant</term>
+ <listitem>
+ <para>
+ L'instance est associ�e au contexte de persistance.
+ Elle poss�de une identit� persistante (valeur de cl� primaire)
+ et, peut-�tre, un enregistrement correspondant dans la base.
+ Pour un contexte de persistance particulier, Hibernate
+ <emphasis>garantit</emphasis> que l'identit�
persistante
+ est �quivalente � l'identit� Java (emplacement m�moire de
l'objet)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>d�tach�</term>
+ <listitem>
+ <para>
+ L'instance a �t� associ�e au contexte de persistance mais ce
+ contexte a �t� ferm�, ou l'instance a �t� s�rialis�e vers un
+ autre processus. Elle poss�de une identit� persistante et
+ peut-�tre un enregistrement correspondant dans la base.
+ Pour des instances d�tach�es, Hibernate ne donne aucune
+ garantie sur la relation entre l'identit� persistante et
+ l'identit� Java.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="architecture-jmx" revision="1">
+ <title>Int�gration JMX</title>
+ <para>
+ JMX est le standard J2EE de gestion des composants Java.
+ Hibernate peut �tre g�r� via un service JMX standard. Nous fournissons une
impl�mentation
+ d'un MBean dans la distribution :
<literal>org.hibernate.jmx.HibernateService</literal>.
+ </para>
+
+ <para>
+ Pour avoir un exemple sur la mani�re de d�ployer Hibernate en tant que
service JMX dans le
+ serveur d'application JBoss Application Server, r�f�rez vous au guide
utilisateur JBoss (JBoss User Guide).
+ Si vous d�ployez Hibernate via JMX sur JBoss AS, vous aurez �galement les
b�n�fices suivants :
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Gestion de la session :</emphasis> Le cycle de
vie de la <literal>Session</literal>
+ Hibernate peut �tre automatiquement limit�e � la port�e d'une
transaction JTA.
+ Cela signifie que vous n'avez plus besoin d'ouvrir et de
fermer la <literal>Session</literal>
+ manuellement, cela devient le travail de l'intercepteur EJB de
JBoss. Vous n'avez
+ pas non plus � vous occuper des d�marcations des transactions dans
votre code (sauf
+ si vous voulez �crire une couche de persistance qui soit portable,
dans ce cas vous
+ pouvez utiliser l'API optionnelle
<literal>Transaction</literal> d'Hibernate).
+ Vous appelez l'<literal>HibernateContext</literal>
pour acc�der � la <literal>Session</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>D�ploiement HAR :</emphasis> Habituellement
vous d�ployez le service JMX
+ Hibernate en utilisant le descripteur de d�ploiement de JBoss (dans
un fichier EAR et/ou un SAR),
+ il supporte toutes les options de configuration usuelles d'une
<literal>SessionFactory</literal>
+ Hibernate. Cependant, vous devez toujours nommer tous vos fichiers de
mapping dans le
+ descripteur de d�ploiement. Si vous d�cidez d'utiliser le
d�ploiement optionnel sous forme
+ de HAR, JBoss d�tectera automatiquement tous vos fichiers de mapping
dans votre fichier HAR.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Consultez le guide d'utilisation de JBoss AS pour plus d'informations
sur ces options.
+ </para>
+
+ <para>
+ Les statistiques pendant l'ex�cution d'Hibernate (au runtime) sont
une
+ autre fonctionnalit� disponible en tant que service JMX. Voyez pour cela
+ <xref linkend="configuration-optional-statistics"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-jca" revision="1">
+ <title>Support JCA</title>
+ <para>
+ Hibernate peut aussi �tre configur� en tant que connecteur JCA. R�f�rez-vous
au site
+ web pour de plus amples d�tails. Il est important de noter que le support JCA
d'Hibernate
+ est encore consid�r� comme exp�rimental.
+ </para>
+ </sect1>
+
+ <sect1 id="architecture-current-session" revision="1">
+ <title>Sessions Contextuelles</title>
+ <para>
+ Certaines applications utilisant Hibernate ont besoin d'une sorte de
session "contextuelle", o�
+ une session est li�e � la port�e d'un contexte particulier. Cependant,
les applications ne d�finissent
+ pas toutes la notion de contexte de la m�me mani�re, et diff�rents contextes
d�finissent diff�rentes
+ port�es � la notion de "courant". Les applications � base
d'Hibernate, versions pr�c�dentes � la 3.0
+ utilisaient g�n�ralement un principe maison de sessions contextuelles bas�es
sur le <literal>ThreadLocal</literal>,
+ ainsi que sur des classes utilitaires comme
<literal>HibernateUtil</literal>, ou utilisaient des
+ framework tiers (comme Spring ou Pico) qui fournissaient des sessions
contextuelles bas�es sur
+ l'utilisation de proxy/interception.
+ </para>
+ <para>
+ A partir de la version 3.0.1, Hibernate a ajout� la m�thode
<literal>SessionFactory.getCurrentSession()</literal>.
+ Initialement, cela demandait l'usage de transactions
<literal>JTA</literal>, o� la
+ transaction <literal>JTA</literal> d�finissait la port�e et le
contexte de la session courante.
+ L'�quipe Hibernate pense que, �tant donn�e la maturit� des impl�mentations
de <literal>JTA TransactionManager</literal> ,
+ la plupart (sinon toutes) des applications devraient utiliser la gestion des
transactions par <literal>JTA</literal>
+ qu'elles soient ou non d�ploy�es dans un conteneur
<literal>J2EE</literal>. Par cons�quent,
+ vous devriez toujours contextualiser vos sessions, si vous en avez besoin, via
la m�thode bas�e sur JTA.
+ </para>
+ <para>
+ Cependant, depuis la version 3.1, la logique derri�re
+ <literal>SessionFactory.getCurrentSession()</literal> est
d�sormais branchable.
+ A cette fin, une nouvelle interface d'extension
(<literal>org.hibernate.context.CurrentSessionContext</literal>)
+ et un nouveau param�tre de configuration
(<literal>hibernate.current_session_context_class</literal>)
+ ont �t� ajout�s pour permettre de configurer d'autres moyens de d�finir
la port�e et le contexte des
+ sessions courantes.
+ </para>
+ <para>
+ Allez voir les Javadocs de l'interface
<literal>org.hibernate.context.CurrentSessionContext</literal>
+ pour une description d�taill�e de son contrat. Elle d�finit une seule
m�thode,
+ <literal>currentSession()</literal>, depuis laquelle
l'impl�mentation est responsable
+ de traquer la session courante du contexte. Hibernate fournit deux
impl�mentation
+ de cette interface.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+
<literal>org.hibernate.context.JTASessionContext</literal> - les sessions
courantes sont
+ associ�es � une transaction <literal>JTA</literal>. La
logique est la m�me que
+ l'ancienne approche bas�e sur JTA. Voir les javadocs pour les
d�tails.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+
<literal>org.hibernate.context.ThreadLocalSessionContext</literal> - les
sessions
+ courantes sont associ�es au thread d'ex�cution. Voir les javadocs
pour les d�tails.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Les deux impl�mentations fournissent un mod�le de programmation de type
"une session - une transaction
+ � la base de donn�es", aussi connu sous le nom de
<emphasis>session-per-request</emphasis>.
+ Le d�but et la fin d'une session Hibernate sont d�finis par la dur�e
d'une transaction de base de donn�es.
+ Si vous utilisez une d�marcation programmatique de la transaction (par
exemple sous J2SE ou JTA/UserTransaction/BMT),
+ nous vous conseillons d'utiliser l'API Hibernate
<literal>Transaction</literal> pour masquer le syst�me
+ de transaction utilis�. Si vous ex�cutez sous un conteneur EJB qui supporte
CMT, vous n'avez besoin d'aucune
+ op�rations de d�marcations de session ou transaction dans votre code puisque
tout
+ est g�r� de mani�re d�clarative. R�f�rez vous � <xref
linkend="transactions"/> pour plus d'informations
+ et des exemples de code.
+ </para>
+
+ <para>
+ Le param�tre de configuration
<literal>hibernate.current_session_context_class</literal>
+ d�finit quelle impl�mentation de
<literal>org.hibernate.context.CurrentSessionContext</literal>
+ doit �tre utilis�e. Notez que pour assurer la compatibilit� avec les versions
pr�c�dentes, si
+ ce param�tre n'est pas d�fini mais qu'un
<literal>org.hibernate.transaction.TransactionManagerLookup</literal>
+ est configur�, Hibernate utilisera le
<literal>org.hibernate.context.JTASessionContext</literal>.
+ La valeur de ce param�tre devrait juste nommer la classe d'impl�mentation
� utiliser,
+ pour les deux impl�mentations fournies, il y a cependant deux alias
correspondant: "jta" et "thread".
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied:
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/association_mapping.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/association_mapping.xml)
===================================================================
---
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/association_mapping.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/association_mapping.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,623 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="associations">
+
+ <title>Mapper les associations</title>
+
+ <sect1 id="assoc-intro" revision="1">
+ <title>Introduction</title>
+
+ <para>
+ Correctement mapper les associations est souvent la t�che la plus difficile.
+ Dans cette section nous traiterons les cas classiques les uns apr�s les
autres.
+ Nous commencerons d'abbord par les mappings unidirectionnels, puis nous
aborderons
+ la question des mappings bidirectionnels. Nous illustrerons tous nos exemples
+ avec les classes <literal>Person</literal> et
<literal>Address</literal>.
+ </para>
+
+ <para>
+ Nous utiliserons deux crit�res pour classer les associations : le premier
+ sera de savoir si l'association est b�ti sur une table suppl�mentaire
d'association
+ et le deuxieme sera bas� sur la multiplicit� de cette association.
+ </para>
+
+ <para>
+ Autoriser une cl� �trang�re nulle est consid�r� comme un mauvais choix dans
+ la construction d'un mod�le de donn�es. Nous supposerons donc que dans tous
+ les exemples qui vont suivre on aura interdit la valeur nulle pour les cl�s
+ �trang�res. Attention, ceci ne veut pas dire que Hibernate ne supporte pas
+ les cl�s �trang�res pouvant prendre des valeurs nulles, les exemples qui suivent
+ continueront de fonctionner si vous d�cidiez ne plus imposer la contrainte
+ de non-nullit� sur les cl�s �trang�res.
+ </para>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional" revision="1">
+ <title>Association unidirectionnelle</title>
+
+ <sect2 id="assoc-unidirectional-m21" >
+ <title>plusieurs � un</title>
+
+ <para>
+ Une <emphasis>association plusieurs-�-un (many-to-one)
unidirectionnelle </emphasis>
+ est le type que l'on rencontre le plus souvent dans les associations
unidirectionnelles.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-121">
+ <title>un � un</title>
+
+ <para>
+ une <emphasis>association un-�-un (one-to-one) sur une cl�
�trang�re</emphasis>
+ est presque identique. La seule diff�rence est sur la contrainte
d'unicit� que
+ l'on impose � cette colonne.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null
unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ Une <emphasis>association un-�-un (one-to-one) unidirectionnelle sur
une cl� primaire</emphasis>
+ utilise un g�n�rateur d'identifiant particulier. (Remarquez que nous
avons invers� le sens de cette
+ association dans cet exemple.)
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person" constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-12m">
+ <title>un � plusieurs</title>
+
+ <para>
+ Une <emphasis>association un-�-plusieurs (one-to-many)
unidirectionnelle sur une
+ cl� �trang�re</emphasis> est vraiment inhabituelle, et n'est pas
vraiment recommand�e.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses">
+ <key column="personId"
+ not-null="true"/>
+ <one-to-many class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( addressId bigint not null primary key, personId bigint not null )
+ ]]></programlisting>
+
+ <para>
+ Nous pensons qu'il est pr�f�rable d'utiliser une table de jointure
pour ce type d'association.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-unidirectional-join" revision="1">
+ <title>Associations unidirectionnelles avec tables de
jointure</title>
+
+ <sect2 id="assoc-unidirectional-join-12m">
+ <title>un � plusieurs</title>
+
+ <para>
+ Une <emphasis>association unidirectionnelle un-�-plusieurs
(one-to-many) avec
+ une table de jointure</emphasis> est un bien meilleur choix.
+ Remarquez qu'en sp�cifiant
<literal>unique="true"</literal>,
+ on a chang� la multiplicit� plusieurs-�-plusieurs (many-to-many) pour
+ un-�-plusieurs (one-to-many).
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m21">
+ <title>plusieurs � un</title>
+
+ <para>
+ Une <emphasis>assiociation plusieurs-�-un (many-to-one)
unidirectionnelle sur
+ une table de jointure</emphasis> est tr�s fr�quente quand
l'association est optionnelle.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId" unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not
null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-121">
+ <title>un � un</title>
+
+ <para>
+ Une <emphasis>association unidirectionnelle un-�-un (one-to-one) sur
une table
+ de jointure</emphasis> est extr�mement rare mais envisageable.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not
null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-unidirectional-join-m2m">
+ <title>plusieurs � plusieurs</title>
+
+ <para>
+ Finallement, nous avons <emphasis>l'association unidirectionnelle
plusieurs-�-plusieurs (many-to-many)</emphasis>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary
key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional" revision="1">
+ <title>Associations bidirectionnelles</title>
+
+ <sect2 id="assoc-bidirectional-m21" revision="2">
+ <title>un � plusieurs / plusieurs � un</title>
+
+ <para>
+ Une <emphasis>association bidirectionnelle plusieurs � un
(many-to-one)</emphasis>
+ est le type d'association que l'on rencontre le plus souvent.
(c'est la fa�on standard de cr�er
+ des relations parents/enfants.)
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true">
+ <key column="addressId"/>
+ <one-to-many class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ Si vous utilisez une <literal>List</literal> (ou toute autre
collection index�e) vous devez
+ param�trer la colonne <literal>key</literal> de la cl� �trang�re
� <literal>not null</literal>,
+ et laisser Hibernate g�rer l'association depuis l'extr�mit�
collection pour maintenir l'index
+ de chaque �l�ment (rendant l'autre extr�mit� virtuellement inverse en
param�trant
+ <literal>update="false"</literal> et
<literal>insert="false"</literal>):
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id"/>
+ ...
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ insert="false"
+ update="false"/>
+</class>
+
+<class name="Address">
+ <id name="id"/>
+ ...
+ <list name="people">
+ <key column="addressId" not-null="true"/>
+ <list-index column="peopleIdx"/>
+ <one-to-many class="Person"/>
+ </list>
+</class>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-121">
+ <title>Un � un</title>
+
+ <para>
+ Une <emphasis>association bidirectionnelle un � un (one-to-one) sur une
cl� �trang�re</emphasis>
+ est aussi tr�s fr�quente.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <many-to-one name="address"
+ column="addressId"
+ unique="true"
+ not-null="true"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="person"
+ property-ref="address"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null
unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ <para>
+ Une <emphasis>association bidirectionnelle un-�-un (one-to-one) sur une
cl� primaire</emphasis>
+ utilise un g�n�rateur particulier d'id.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <one-to-one name="address"/>
+</class>
+
+<class name="Address">
+ <id name="id" column="personId">
+ <generator class="foreign">
+ <param name="property">person</param>
+ </generator>
+ </id>
+ <one-to-one name="person"
+ constrained="true"/>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-bidirectional-join" revision="1">
+ <title>Associations bidirectionnelles avec table de jointure</title>
+
+ <sect2 id="assoc-bidirectional-join-12m">
+ <title>un � plusieurs / plusieurs � un</title>
+
+ <para>
+ Une <emphasis>association bidirectionnelle un-�-plusieurs (one-to-many)
sur une table de jointure </emphasis>.
+ Remarquez que <literal>inverse="true"</literal> peut
s'appliquer sur les deux extr�mit�s de l'
+ association, sur la collection, ou sur la jointure.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses"
+ table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ unique="true"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ inverse="true"
+ optional="true">
+ <key column="addressId"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null primary
key )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-121">
+ <title>Un � un</title>
+
+ <para>
+ Une <emphasis>association bidirectionnelle un-�-un (one-to-one) sur une
table de jointure</emphasis>
+ est extr�mement rare mais envisageable.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true">
+ <key column="personId"
+ unique="true"/>
+ <many-to-one name="address"
+ column="addressId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <join table="PersonAddress"
+ optional="true"
+ inverse="true">
+ <key column="addressId"
+ unique="true"/>
+ <many-to-one name="person"
+ column="personId"
+ not-null="true"
+ unique="true"/>
+ </join>
+</class>]]></programlisting>
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not
null unique )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="assoc-bidirectional-join-m2m" revision="1">
+ <title>plusieurs � plusieurs</title>
+
+ <para>
+ Finallement nous avons <emphasis>l'association bidirectionnelle
plusieurs � plusieurs</emphasis>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <id name="id" column="personId">
+ <generator class="native"/>
+ </id>
+ <set name="addresses" table="PersonAddress">
+ <key column="personId"/>
+ <many-to-many column="addressId"
+ class="Address"/>
+ </set>
+</class>
+
+<class name="Address">
+ <id name="id" column="addressId">
+ <generator class="native"/>
+ </id>
+ <set name="people" inverse="true"
table="PersonAddress">
+ <key column="addressId"/>
+ <many-to-many column="personId"
+ class="Person"/>
+ </set>
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary
key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+ ]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="assoc-complex">
+ <title>Des mappings plus complexes</title>
+
+ <para>
+ Des associations encore plus complexes sont
<emphasis>extr�mement</emphasis> rares.
+ Hibernate permet de g�rer des situations plus complexes en utilisant des
+ parties SQL dans les fichiers de mapping. Par exemple, si une table
+ avec l'historiques des informations d'un compte d�finit les colonnes
+ <literal>accountNumber</literal>,
<literal>effectiveEndDate</literal>
+ et <literal>effectiveStartDate</literal>, mapp�es de telle
sorte:
+ </para>
+
+ <programlisting><![CDATA[<properties
name="currentAccountKey">
+ <property name="accountNumber" type="string"
not-null="true"/>
+ <property name="currentAccount" type="boolean">
+ <formula>case when effectiveEndDate is null then 1 else 0
end</formula>
+ </property>
+</properties>
+<property name="effectiveEndDate" type="date"/>
+<property name="effectiveStateDate" type="date"
not-null="true"/>]]></programlisting>
+
+ <para>
+ alors nous pouvons mapper une association � l'instance
<emphasis>courante</emphasis>
+ (celle avec une <literal>effectiveEndDate</literal>) nulle en
utilisant:
+ </para>
+
+ <programlisting><![CDATA[<many-to-one
name="currentAccountInfo"
+ property-ref="currentAccountKey"
+ class="AccountInfo">
+ <column name="accountNumber"/>
+ <formula>'1'</formula>
+</many-to-one>]]></programlisting>
+
+ <para>
+ Dans un exemple plus complexe, imaginez qu'une association entre
+ <literal>Employee</literal> et
<literal>Organization</literal> est g�r�e
+ dans une table <literal>Employment</literal> pleines de donn�es
historiques.
+ Dans ce cas, une association vers l'employeur <emphasis>le plus
r�cent</emphasis>
+ (celui avec la <literal>startDate</literal> la plus r�cente)
pourrait �tre mapp�e comme cela:
+ </para>
+
+ <programlisting><![CDATA[<join>
+ <key column="employeeId"/>
+ <subselect>
+ select employeeId, orgId
+ from Employments
+ group by orgId
+ having startDate = max(startDate)
+ </subselect>
+ <many-to-one name="mostRecentEmployer"
+ class="Organization"
+ column="orgId"/>
+</join>]]></programlisting>
+
+ <para>
+ Vous pouvez �tre cr�atif grace � ces possibilit�s, mais il est g�n�ralement
plus pratique
+ d'utiliser des requ�tes HQL ou criteria dans ce genre de situation.
+ </para>
+
+ </sect1>
+
+
+</chapter>
+
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/basic_mapping.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/basic_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/basic_mapping.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/basic_mapping.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,3117 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<chapter id="mapping">
+ <title>Mapping O/R basique</title>
+ <sect1 id="mapping-declaration" revision="1">
+ <title>D�claration de Mapping</title>
+ <para>
+ Les mappings Objet/relationnel sont g�n�ralement d�finis dans un document
XML.
+ Le document de mapping est con�u pour �tre lisible et �ditable � la main.
+ Le langage de mapping est Java-centrique, c'est � dire que les mappings
sont construits
+ � partir des d�clarations des classes persistantes et non des d�clarations
des tables.
+ </para>
+ <para>
+ Remarquez que m�me si beaucoup d'utilisateurs de Hibernate pr�f�rent
�crire les
+ fichiers de mappings � la main, plusieurs outils existent pour g�n�rer ce
document,
+ notamment XDoclet, Middlegen et AndroMDA.
+ </para>
+ <para>D�marrons avec un exemple de mapping :</para>
+ <programlisting id="mapping-declaration-ex1"
revision="1"><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat"
+ table="cats"
+ discriminator-value="C">
+
+ <id name="id">
+ <generator class="native"/>
+ </id>
+
+ <discriminator column="subclass"
+ type="character"/>
+
+ <property name="weight"/>
+
+ <property name="birthdate"
+ type="date"
+ not-null="true"
+ update="false"/>
+
+ <property name="color"
+ type="eg.types.ColorUserType"
+ not-null="true"
+ update="false"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <property name="litterId"
+ column="litterId"
+ update="false"/>
+
+ <many-to-one name="mother"
+ column="mother_id"
+ update="false"/>
+
+ <set name="kittens"
+ inverse="true"
+ order-by="litter_id">
+ <key column="mother_id"/>
+ <one-to-many class="Cat"/>
+ </set>
+
+ <subclass name="DomesticCat"
+ discriminator-value="D">
+
+ <property name="name"
+ type="string"/>
+
+ </subclass>
+
+ </class>
+
+ <class name="Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+ <para>
+ Etudions le contenu du document de mapping. Nous d�crirons uniquement
+ les �l�ments et attributs du document utilis�s par Hibernate �
l'ex�cution.
+ Le document de mapping contient aussi des attributs et �l�ments optionnels
+ qui agissent sur le sch�ma de base de donn�es export� par l'outil de
+ g�n�ration de sch�ma. (Par exemple l'attribut
<literal>not-null</literal>.)
+ </para>
+ <sect2 id="mapping-declaration-doctype" revision="2">
+ <title>Doctype</title>
+ <para>
+ Tous les mappings XML devraient utiliser le doctype indiqu�.
+ Ce fichier est pr�sent � l'URL ci-dessus, dans le r�pertoire
+ <literal>hibernate-x.x.x/src/org/hibernate</literal> ou dans
<literal>hibernate3.jar</literal>.
+ Hibernate va toujours chercher la DTD dans son classpath en premier lieu.
Si vous constatez
+ des recherches de la DTD sur Internet, v�rifiez votre d�claration de DTD
par rapport
+ au contenu de votre classpath.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-mapping" revision="3">
+ <title>hibernate-mapping</title>
+ <para>
+ Cet �l�ment a plusieurs attributs optionnels. Les attributs
<literal>schema</literal> et <literal>catalog</literal>
+ indiquent que les tables r�f�renc�es par ce mapping appartiennent au
sch�ma nomm� et/ou au catalogue.
+ S'ils sont sp�cifi�s, les noms de tables seront qualifi�s par les
noms de sch�ma et catalogue.
+ L'attribut <literal>default-cascade</literal> indique
quel type de cascade sera utlis� par d�faut
+ pour les propri�t�s et collections qui ne pr�cisent pas l'attribut
<literal>cascade</literal>.
+ L'attribut <literal>auto-import</literal> nous permet
d'utiliser par d�faut des noms de classes
+ non qualifi�s dans le langage de requ�te.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="hm1" coords="2 55"/>
+ <area id="hm2" coords="3 55"/>
+ <area id="hm3" coords="4 55"/>
+ <area id="hm4" coords="5 55"/>
+ <area id="hm5" coords="6 55"/>
+ <area id="hm6" coords="7 55"/>
+ <area id="hm7" coords="8 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<hibernate-mapping
+ schema="schemaName"
+ catalog="catalogName"
+ default-cascade="cascade_style"
+ default-access="field|property|ClassName"
+ default-lazy="true|false"
+ auto-import="true|false"
+ package="package.name"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="hm1">
+ <para>
+ <literal>schema</literal> (optionnel) : Le nom
d'un sch�ma de base de donn�es.
+ </para>
+ </callout>
+ <callout arearefs="hm2">
+ <para>
+ <literal>catalog</literal> (optionnel) : Le nom
d'un catalogue de base de donn�es.
+ </para>
+ </callout>
+ <callout arearefs="hm3">
+ <para>
+ <literal>default-cascade</literal> (optionnel -
par d�faut vaut : <literal>none</literal>) :
+ Un type de cascade par d�faut.
+ </para>
+ </callout>
+ <callout arearefs="hm4">
+ <para>
+ <literal>default-access</literal> (optionnel -
par d�faut vaut : <literal>property</literal>) :
+ Comment hibernate acc�dera aux propri�t�s. On peut aussi
+ red�finir sa propre impl�mentation de
<literal>PropertyAccessor</literal>.
+ </para>
+ </callout>
+ <callout arearefs="hm5">
+ <para>
+ <literal>default-lazy</literal> (optionnel - par
d�faut vaut : <literal>true</literal>) :
+ Valeur par d�faut pour un attribut
<literal>lazy</literal>
+ non sp�cifi� : celui des mappings de classes et de
collection.
+ </para>
+ </callout>
+ <callout arearefs="hm6">
+ <para>
+ <literal>auto-import</literal> (optionnel - par
d�faut vaut : <literal>true</literal>) :
+ Sp�cifie si l'on peut utiliser des noms de classes
+ non qualifi�s (des classes de ce mapping) dans le langage de
requ�te.
+ </para>
+ </callout>
+ <callout arearefs="hm7">
+ <para>
+ <literal>package</literal> (optionnel) : Pr�fixe
de package par d�faut pour
+ les noms de classe non qualifi�s du document de mapping.
+
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Si deux classes poss�dent le m�me nom de classe (non qualifi�), vous
devez indiquer
+ <literal>auto-import="false"</literal>. Hibernate
lancera une exception
+ si vous essayez d'assigner � deux classes le m�me nom import�.
+ </para>
+ <para>
+ Notez que l'�l�ment <literal>hibernate-mapping</literal>
vous permet d'imbriquer plusieurs mappings de
+ <literal><class></literal> persistantes, comme
dans l'exemple ci-dessus.
+ Cependant la bonne pratique (ce qui est attendu par certains outils) est
+ de mapper une seule classe (ou une seule hi�rarchie de classes)
+ par fichier de mapping et de nommer ce fichier d'apr�s le nom de la
superclasse, par exemple
+ <literal>Cat.hbm.xml</literal>,
<literal>Dog.hbm.xml</literal>, ou en cas d'h�ritage,
+ <literal>Animal.hbm.xml</literal>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-class" revision="3">
+ <title>class</title>
+ <para>
+ D�clarez une classe persistante avec l'�l�ment
<literal>class</literal> :
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="class1" coords="2 55"/>
+ <area id="class2" coords="3 55"/>
+ <area id="class3" coords="4 55"/>
+ <area id="class4" coords="5 55"/>
+ <area id="class5" coords="6 55"/>
+ <area id="class6" coords="7 55"/>
+ <area id="class7" coords="8 55"/>
+ <area id="class8" coords="9 55"/>
+ <area id="class9" coords="10 55"/>
+ <area id="class10" coords="11 55"/>
+ <area id="class11" coords="12 55"/>
+ <area id="class12" coords="13 55"/>
+ <area id="class13" coords="14 55"/>
+ <area id="class14" coords="15 55"/>
+ <area id="class15" coords="16 55"/>
+ <area id="class16" coords="17 55"/>
+ <area id="class17" coords="18 55"/>
+ <area id="class18" coords="19 55"/>
+ <area id="class19" coords="20 55"/>
+ <area id="class20" coords="21 55"/>
+ <area id="class21" coords="22 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<class
+ name="ClassName"
+ table="tableName"
+ discriminator-value="discriminator_value"
+ mutable="true|false"
+ schema="owner"
+ catalog="catalog"
+ proxy="ProxyInterface"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ select-before-update="true|false"
+ polymorphism="implicit|explicit"
+ where="arbitrary sql where condition"
+ persister="PersisterClass"
+ batch-size="N"
+ optimistic-lock="none|version|dirty|all"
+ lazy="true|false"
+ entity-name="EntityName"
+ catalog="catalog"
+ check="arbitrary sql check condition"
+ rowid="rowid"
+ subselect="SQL expression"
+ abstract="true|false"
+ entity-name="EntityName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="class1">
+ <para>
+ <literal>name</literal> (optionnel) : Le nom Java
complet de la classe (ou interface) persistante.
+ Si cet attribut est absent, il est suppos� que ce mapping ne
se rapporte pas � une entit� POJO.
+ </para>
+ </callout>
+ <callout arearefs="class2">
+ <para>
+ <literal>table</literal> (optionnel - par d�faut
le nom (non-qualifi�) de la classe) : Le
+ nom de sa table en base de donn�es.
+ </para>
+ </callout>
+ <callout arearefs="class3">
+ <para>
+ <literal>discriminator-value</literal> (optionnel
- par d�faut le nom de la classe) :
+ Une valeur permettant de distinguer les sous-classes dans le
cas de l'utilisation du polymorphisme.
+ Les valeurs <literal>null</literal> et
<literal>not null</literal> sont autoris�es.
+ </para>
+ </callout>
+ <callout arearefs="class4">
+ <para>
+ <literal>mutable</literal> (optionnel, vaut
<literal>true</literal> par d�faut) : Sp�cifie
+ que des instances de la classe sont (ou non) immuables.
+ </para>
+ </callout>
+ <callout arearefs="class5">
+ <para>
+ <literal>schema</literal> (optionnel) : Surcharge
le nom de sch�ma sp�cifi� par
+ l'�l�ment racine
<literal><hibernate-mapping></literal>.
+ </para>
+ </callout>
+ <callout arearefs="class6">
+ <para>
+ <literal>catalog</literal> (optionnel) :
Surcharge le nom du catalogue sp�cifi� par
+ l'�l�ment racine
<literal><hibernate-mapping></literal>.
+ </para>
+ </callout>
+ <callout arearefs="class7">
+ <para>
+ <literal>proxy</literal> (optionnel) : Sp�cifie
une interface � utiliser pour l'initialisation diff�r�e (lazy loading)
+ des proxies. Vous pouvez indiquer le nom de la classe
elle-m�me.
+ </para>
+ </callout>
+ <callout arearefs="class8">
+ <para>
+ <literal>dynamic-update</literal> (optionnel, par
d�faut � <literal>false</literal>) :
+ Sp�cifie que les <literal>UPDATE</literal> SQL
doivent �tre g�n�r�s � l'ex�cution et contenir
+ uniquement les colonnes dont les valeurs ont �t� modifi�es.
+ </para>
+ </callout>
+ <callout arearefs="class9">
+ <para>
+ <literal>dynamic-insert</literal> (optionnel, par
d�faut � <literal>false</literal>):
+ Sp�cifie que les <literal>INSERT</literal> SQL
doivent �tre g�n�r�s � l'ex�cution et ne contenir
+ que les colonnes dont les valeurs sont non nulles.
+ </para>
+ </callout>
+ <callout arearefs="class10">
+ <para>
+ <literal>select-before-update</literal>
(optionnel, par d�faut � <literal>false</literal>):
+ Sp�cifie que Hibernate ne doit
<emphasis>jamais</emphasis> ex�cuter un <literal>UPDATE</literal>
SQL
+ sans �tre certain qu'un objet a �t� r�ellement modifi�.
Dans certains cas, (en r�alit�, seulement
+ quand un objet transient a �t� associ� � une nouvelle session
par <literal>update()</literal>),
+ cela signifie que Hibernate ex�cutera un
<literal>SELECT</literal> SQL pour s'assurer qu'un
+ <literal>UPDATE</literal> SQL est v�ritablement
n�cessaire.
+ </para>
+ </callout>
+ <callout arearefs="class11">
+ <para>
+ <literal>polymorphism</literal> (optionnel, vaut
<literal>implicit</literal> par d�faut) :
+ D�termine si, pour cette classe, une requ�te polymorphique
implicite ou explicite est utilis�e.
+ </para>
+ </callout>
+ <callout arearefs="class12">
+ <para>
+ <literal>where</literal> (optionnel) sp�cifie une
clause SQL <literal>WHERE</literal>
+ � utiliser lorsque l'on r�cup�re des objets de cette
classe.
+ </para>
+ </callout>
+ <callout arearefs="class13">
+ <para>
+ <literal>persister</literal> (optionnel) :
Sp�cifie un <literal>ClassPersister</literal> particulier.
+ </para>
+ </callout>
+ <callout arearefs="class14">
+ <para>
+ <literal>batch-size</literal> (optionnel, par
d�faut = <literal>1</literal>) : sp�cifie une taille de batch
+ pour remplir les instances de cette classe par identifiant en
une seule requ�te.
+ </para>
+ </callout>
+ <callout arearefs="class15">
+ <para>
+ <literal>optimistic-lock</literal> (optionnel,
par d�faut = <literal>version</literal>) :
+ D�termine la strat�gie de verrou optimiste.
+ </para>
+ </callout>
+ <callout arearefs="class16">
+ <para>
+ <literal>lazy</literal> (optionnel) : D�clarer
<literal>lazy="true"</literal> est un raccourci
+ pour sp�cifier le nom de la classe comme �tant
l'interface <literal>proxy</literal>.
+ </para>
+ </callout>
+ <callout arearefs="class17">
+ <para>
+ <literal>entity-name</literal> (optionnel) :
Hibernate3 permet � une classe d'�tre
+ mapp�e plusieurs fois (potentiellement � plusieurs tables),
et permet aux mappings d'entit� d'�tre
+ repr�sent�s par des Maps ou du XML au niveau Java. Dans ces
cas, vous devez indiquer un nom explicite arbitraire pour
+ les entit�s. Voir <xref
linkend="persistent-classes-dynamicmodels"/> et <xref
linkend="xml"/>
+ pour plus d'informations.
+ </para>
+ </callout>
+ <callout arearefs="class18">
+ <para>
+ <literal>catalog</literal> (optionnel) : The name
of a database catalog used for this
+ class and its table.
+ </para>
+ </callout>
+ <callout arearefs="class19">
+ <para>
+ <literal>check</literal> (optionnel) : expression
SQL utilis�e pour g�n�rer une contrainte
+ de v�rification multi-lignes pour la g�n�ration automatique
de sch�ma.
+ </para>
+ </callout>
+ <callout arearefs="class20">
+ <para>
+ <literal>rowid</literal> (optionnel) : Hibernate
peut utiliser des ROWID sur les bases de
+ donn�es qui utilisent ce m�canisme. Par exemple avec Oracle,
Hibernate peut utiliser la colonne additionnelle
+ <literal>rowid</literal> pour des mises � jour
rapides si cette option vaut <literal>rowid</literal>. Un ROWID repr�sente
+ la localisation physique d'un tuple enregistr�.
+ </para>
+ </callout>
+ <callout arearefs="class21">
+ <para>
+ <literal>subselect</literal> (optionnel) : Permet
de mapper une entit� immuable en lecture-seule
+ sur un sous-select de base de donn�es. Utile pour avoir une
vue au lieu d'une table en base, mais � �viter. Voir plus bas
+ pour plus d'information.
+ </para>
+ </callout>
+ <callout arearefs="class22">
+ <para>
+ <literal>abstract</literal> (optionnel) : Utilis�
pour marquer des superclasses abstraites dans
+ des hi�rarchies de
<literal><union-subclass></literal>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Il est tout � fait possible d'utiliser une interface comme nom
+ de classe persistante. Vous devez alors d�clarer les classes
impl�mentant
+ cette interface en utilisant l'�l�ment
<literal><subclass></literal>.
+ Vous pouvez faire persister toute classe interne
<emphasis>static</emphasis>.
+ Vous devez alors sp�cifier le nom de la classe par la notation habituelle
+ des classes internes c'est � dire
<literal>eg.Foo$Bar</literal>.
+ </para>
+ <para>
+ Les classes immuables,
<literal>mutable="false"</literal>, ne peuvent
+ pas �tre modifi�es ou supprim�es par l'application. Cela permet
+ � Hibernate de faire quelques optimisations mineures sur les
performances.
+ </para>
+ <para>
+ L'attribut optionnnel <literal>proxy</literal> permet les
intialisations
+ diff�r�es des instances persistantes de la classe. Hibernate retournera
+ initialement des proxies CGLIB qui impl�mentent l'interface nomm�e.
+ Le v�ritable objet persistant ne sera charg� que lorsque une m�thode du
proxy
+ sera appel�e. Voir plus bas le paragraphe abordant les proxies et le
chargement diff�r� (lazy initialization).
+ </para>
+ <para>
+ Le polymorphisme <emphasis>implicite</emphasis>
+ signifie que les instances de la classe seront retourn�es par une
+ requ�te qui utilise les noms de la classe ou de chacune de ses
+ superclasses ou encore des interfaces impl�ment�es par cette classe
+ ou ses superclasses. Les instances des classes filles seront retourn�es
+ par une requ�te qui utilise le nom de la classe elle m�me. Le
polymorphisme
+ <emphasis>explicite</emphasis> signifie que les instances
de la classe
+ ne seront retourn�es que par une requ�te qui utilise explicitement
+ son nom et que seules les instances des classes filles d�clar�es dans les
�l�ments
+ <literal><subclass></literal> ou
<literal><joined-subclass></literal>
+ seront retourn�es. Dans la majorit�s des cas la valeur par d�faut,
+ <literal>polymorphism="implicit"</literal>,
+ est appropri�e. Le polymorphisme explicite est utile lorsque deux
+ classes diff�rentes sont mapp�es � la m�me table (ceci permet
d'�crire
+ une classe "l�g�re" qui ne contient qu'une partie des
colonnes de
+ la table - voir la partie design pattern du site communautaire).
+ </para>
+ <para>
+ L'attribut <literal>persister</literal> vous permet de
customiser
+ la strat�gie utilis�e pour la classe. Vous pouvez, par exemple, sp�cifier
+ votre propre sous-classe de
<literal>org.hibernate.persister.EntityPersister</literal> ou
+ vous pourriez aussi cr�er une nouvelle impl�mentation de l'interface
<literal>org.hibernate.persister.ClassPersister</literal>
+ qui proposerait une persistance via, par exemple, des appels de
proc�dures
+ stock�es, de la s�rialisation vers des fichiers plats ou un annuaire
LDAP.
+ Voir <literal>org.hibernate.test.CustomPersister</literal>
pour un exemple simple (d'une "persistance"
+ vers une <literal>Hashtable</literal>).
+ </para>
+ <para>
+ Notez que les param�tres <literal>dynamic-update</literal> et
<literal>dynamic-insert</literal>
+ ne sont pas h�rit�s par les sous-classes et peuvent donc �tre sp�cifi�s
+ pour les �l�ments <literal><subclass></literal>
ou <literal><joined-subclass></literal>
+ Ces param�tres peuvent am�liorer les performances dans certains cas,
+ mais peuvent aussi les amoindrir. A utiliser en connaissance de causes.
+ </para>
+ <para>
+ L'utilisation de <literal>select-before-update</literal>
va g�n�ralement
+ faire baisser les performances. Ce param�tre est pratique
+ pour pr�venir l'appel inutile d'un trigger sur modification quand
on
+ r�attache un graphe d'instances � une
<literal>Session</literal>.
+ </para>
+ <para>
+ Si vous utilisez le <literal>dynamic-update</literal>, les
diff�rentes
+ strat�gies de verrouillage optimiste (optimistic locking) sont les
suivantes:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>version</literal> v�rifie les colonnes
version/timestamp
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>all</literal> v�rifie toutes les colonnes
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>dirty</literal> v�rifie les colonnes
modifi�es, permettant des updates concurrents
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>none</literal> pas de verrouillage
optimiste
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Nous encourageons <emphasis>tr�s</emphasis> fortement
l'utilisation
+ de colonnes de version/timestamp pour le verrouillage optimiste
+ avec Hibernate. C'est la meilleure strat�gie en regard des
performances
+ et la seule qui g�re correctement les modifications sur les objets
d�tach�s
+ (c'est � dire lorsqu'on utilise
<literal>Session.merge()</literal>).
+ </para>
+ <para>
+ Il n'y a pas de diff�rence entre table et vue pour le mapping
Hibernate,
+ tant que c'est transparent au niveau base de donn�es (remarquez
+ que certaines BDD ne supportent pas les vues correctement, notamment
+ pour les updates). Vous rencontrerez peut-�tre des cas o� vous
+ souhaitez utiliser une vue mais ne pouvez pas en cr�er sur votre BDD
+ (par exemple � cause de sch�mas anciens et fig�s). Dans ces cas,
+ vous pouvez mapper une entit� immuable en lecture seule sur un
sous-select SQL donn�:
+ </para>
+ <programlisting><![CDATA[<class name="Summary">
+ <subselect>
+ select item.name, max(bid.amount), count(*)
+ from item
+ join bid on bid.item_id = item.id
+ group by item.name
+ </subselect>
+ <synchronize table="item"/>
+ <synchronize table="bid"/>
+ <id name="name"/>
+ ...
+</class>]]></programlisting>
+ <para>
+ D�clarez les tables � synchroniser avec cette entit� pour assurer
+ que le flush automatique se produise correctement,
+ et pour que les requ�tes sur l'entit� d�riv�e ne renvoient pas des
donn�es p�rim�es.
+ Le lit�ral <literal><subselect></literal> est
disponible
+ comme attribut ou comme �l�ment de mapping.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-id" revision="4">
+ <title>id</title>
+ <para>
+ Les classes mapp�es <emphasis>doivent</emphasis> d�clarer la
+ clef primaire de la table en base de donn�es.
+ La plupart des classes auront aussi une propri�t� de type
+ javabean pr�sentant l'identifiant unique d'une instance.
+ L'�l�ment <literal><id></literal> sert �
d�finir le
+ mapping entre cette propri�t� et la clef primaire en base.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="id1" coords="2 65"/>
+ <area id="id2" coords="3 65"/>
+ <area id="id3" coords="4 65"/>
+ <area id="id4" coords="5 65"/>
+ <area id="id5" coords="6 65"/>
+ </areaspec>
+ <programlisting><![CDATA[<id
+ name="propertyName"
+ type="typename"
+ column="column_name"
+ unsaved-value="null|any|none|undefined|id_value"
+ access="field|property|ClassName">
+
+ <generator class="generatorClass"/>
+</id>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="id1">
+ <para>
+ <literal>name</literal> (optionnel) : Nom de la
propri�t� qui sert d'identifiant.
+ </para>
+ </callout>
+ <callout arearefs="id2">
+ <para>
+ <literal>type</literal> (optionnel) : Nom
indiquant le type Hibernate.
+ </para>
+ </callout>
+ <callout arearefs="id3">
+ <para>
+ <literal>column</literal> (optionnel - le nom de
la propri�t� est pris par d�faut) : Nom de la clef primaire.
+ </para>
+ </callout>
+ <callout arearefs="id4">
+ <para>
+ <literal>unsaved-value</literal> (optionnel - par
d�faut une valeur "bien choisie") :
+ Une valeur de la propri�t� d'identifiant qui indique que
l'instance est nouvellement
+ instanci�e (non sauvegard�e), et qui la distingue des
instances <literal>transient</literal>s qui ont
+ �t� sauvegard�es ou charg�es dans une session pr�c�dente.
+ </para>
+ </callout>
+ <callout arearefs="id5">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut
<literal>property</literal>) : La strat�gie que doit utiliser Hibernate
+ pour acc�der aux valeurs des propri�t�s.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Si l'attribut <literal>name</literal> est absent,
Hibernate consid�re que la classe ne poss�de pas de propri�t� identifiant.
+ </para>
+ <para>
+ L'attribut <literal>unsaved-value</literal> est important
! Si
+ l'identifiant de votre classe n'a pas une valeur par d�faut
compatible avec
+ le comportement standard de Java (z�ro ou null), vous devez alors
pr�ciser la valeur par d�faut.
+ </para>
+ <para>
+ La d�claration alternative
<literal><composite-id></literal>
+ permet l'accc�s aux donn�es d'anciens syst�mes qui utilisent des
+ clefs compos�es. Son utilisation est fortement d�conseill�e pour
d'autres cas.
+ </para>
+ <sect3 id="mapping-declaration-id-generator"
revision="2">
+ <title>Generator</title>
+ <para>
+ L'�l�ment fils
<literal><generator></literal> nomme une classe Java utilis�e
pour g�n�rer
+ les identifiants uniques pour les instances des classes
persistantes. Si des param�tres sont requis
+ pour configurer ou initialiser l'instance du g�n�rateur, ils
sont pass�s en utilisant l'�l�ment
<literal><param></literal>.
+ </para>
+ <programlisting><![CDATA[<id name="id"
type="long" column="cat_id">
+ <generator class="org.hibernate.id.TableHiLoGenerator">
+ <param name="table">uid_table</param>
+ <param name="column">next_hi_value_column</param>
+ </generator>
+</id>]]></programlisting>
+ <para>
+ Tous les g�n�rateurs doivent impl�menter l'interface
<literal>org.hibernate.id.IdentifierGenerator</literal>.
+ C'est une interface tr�s simple ; certaines applications
peuvent proposer leur propre impl�mentations sp�cialis�es.
+ Cependant, Hibernate propose une s�rie d'impl�mentations
int�gr�es. Il existe des noms raccourcis pour les g�n�rateurs int�gr�s :
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal>increment</literal>
+ </term>
+ <listitem>
+ <para>
+ G�n�re des identifiants de type
<literal>long</literal>, <literal>short</literal> ou
+ <literal>int</literal> qui ne sont
uniques que si aucun autre processus n'ins�re de donn�es dans la m�me table.
+ <emphasis>Ne pas utiliser en environnement
clusteris�.</emphasis>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>identity</literal>
+ </term>
+ <listitem>
+ <para>
+ Utilisation de la colonne identity de DB2, MySQL, MS
SQL Server, Sybase et
+ HypersonicSQL. L'identifiant renvoy� est de type
<literal>long</literal>,
+ <literal>short</literal> ou
<literal>int</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>sequence</literal>
+ </term>
+ <listitem>
+ <para>
+ Utilisation des s�quences dans DB2, PostgreSQL,
Oracle, SAP DB, McKoi ou d'un g�n�rateur dans Interbase.
+ L'identifiant renvoy� est de type
<literal>long</literal>,
+ <literal>short</literal> ou
<literal>int</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>hilo</literal>
+ </term>
+ <listitem>
+ <para
id="mapping-declaration-id-hilodescription" revision="1">
+ Utilise un algorithme hi/lo pour g�n�rer de fa�on
efficace des identifiants de type
+ <literal>long</literal>,
<literal>short</literal> ou <literal>int</literal>,
+ en prenant comme source de valeur "hi" une
table et une colonne (par d�faut
+ <literal>hibernate_unique_key</literal>
et
+ <literal>next_hi</literal>
respectivement). L'algorithme hi/lo g�n�re des identifiants uniques
+ pour une base de donn�es particuli�re seulement.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>seqhilo</literal>
+ </term>
+ <listitem>
+ <para>
+ Utilise un algorithme hi/lo pour g�n�rer efficacement
des identifiants de type
<literal>long</literal>, <literal>short</literal> ou
<literal>int</literal>,
+ �tant donn� un nom de s�quence en base.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>uuid</literal>
+ </term>
+ <listitem>
+ <para>
+ Utilise un algorithme de type UUID 128 bits pour
g�n�rer des identifiants de
+ type string, unique au sein d'un r�seau
(l'adresse IP est utilis�e).
+ Le UUID en cod� en une cha�ne de nombre h�xad�cimaux
de longueur 32.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>guid</literal>
+ </term>
+ <listitem>
+ <para>
+ Utilise une cha�ne GUID g�n�r�e par la base pour MS
SQL Server et MySQL.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>native</literal>
+ </term>
+ <listitem>
+ <para>
+ Choisit <literal>identity</literal>,
<literal>sequence</literal> ou
+ <literal>hilo</literal> selon les
possibilit�s offertes par la base de donn�es sous-jacente.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>assigned</literal>
+ </term>
+ <listitem>
+ <para>
+ Laisse l'application affecter un identifiant �
l'objet avant que la m�tode
+ <literal>save()</literal> soit appel�e.
Il s'agit de la strat�gie par d�faut
+ si aucun
<literal><generator></literal> n'est sp�cifi�.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>select</literal>
+ </term>
+ <listitem>
+ <para>
+ R�cup�re une clef primaire assign�e par un trigger en
s�lectionnant
+ la ligne par une clef unique quelconque.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>foreign</literal>
+ </term>
+ <listitem>
+ <para>
+ Utilise l'identifiant d'un objet associ�.
Habituellement utilis� en conjonction
+ avec une association
<literal><one-to-one></literal> sur la clef primaire.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect3>
+ <sect3 id="mapping-declaration-id-hilo"
revision="1">
+ <title>algorithme Hi/lo</title>
+ <para>
+ Les g�n�rateurs <literal>hilo</literal> et
<literal>seqhilo</literal> proposent deux impl�mentations
+ alternatives de l'algorithme hi/lo, une approche largement
utilis�e pour g�n�rer des identifiants. La
+ premi�re impl�mentation n�cessite une table "sp�ciale" en
base pour h�berger la prochaine valeur "hi" disponible.
+ La seconde utilise une s�quence de type Oracle (quand la base
sous-jacente le propose).
+ </para>
+ <programlisting><![CDATA[<id name="id"
type="long" column="cat_id">
+ <generator class="hilo">
+ <param name="table">hi_value</param>
+ <param name="column">next_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+ <programlisting><![CDATA[<id name="id"
type="long" column="cat_id">
+ <generator class="seqhilo">
+ <param name="sequence">hi_value</param>
+ <param name="max_lo">100</param>
+ </generator>
+</id>]]></programlisting>
+ <para>
+ Malheureusement, vous ne pouvez pas utilisez
<literal>hilo</literal> quand vous apportez
+ votre propre <literal>Connection</literal> � Hibernate.
Quand Hibernate utilise une datasource du serveur
+ d'application pour obtenir des connexions inscrites avec JTA,
vous devez correctement configurer
+
<literal>hibernate.transaction.manager_lookup_class</literal>.
+ </para>
+ </sect3>
+ <sect3 id="mapping-declaration-id-uuid">
+ <title>UUID algorithm</title>
+ <para>
+ Le contenu du UUID est : adresse IP, date de d�marrage de la JVM
(pr�cis au quart de seconde),
+ l'heure syst�me et un compteur (unique au sein de la JVM). Il
n'est pas possible d'obtenir l'adresse
+ MAC ou une adresse m�moire � partir de Java, c'est donc le mieux
que l'on puisse faire sans utiliser JNI.
+ </para>
+ </sect3>
+ <sect3 id="mapping-declaration-id-sequences">
+ <title>Colonnes identifiantes et s�quences</title>
+ <para>
+ Pour les bases qui impl�mentent les colonnes "identit�"
(DB2, MySQL, Sybase, MS SQL),
+ vous pouvez utiliser la g�n�ration de clef par
<literal>identity</literal>.
+ Pour les bases qui impl�mentent les s�quences (DB2, Oracle,
PostgreSQL, Interbase, McKoi, SAP DB)
+ vous pouvez utiliser la g�n�ration de clef par
<literal>sequence</literal>. Ces deux m�thodes n�cessitent
+ deux requ�tes SQL pour ins�rer un objet.
+ </para>
+ <programlisting><![CDATA[<id name="id"
type="long" column="person_id">
+ <generator class="sequence">
+ <param name="sequence">person_id_sequence</param>
+ </generator>
+</id>]]></programlisting>
+ <programlisting><![CDATA[<id name="id"
type="long" column="person_id" unsaved-value="0">
+ <generator class="identity"/>
+</id>]]></programlisting>
+ <para>Pour le d�veloppement multi-plateformes, la strat�gie
<literal>native</literal> choisira
+ entre les m�thodes <literal>identity</literal>,
<literal>sequence</literal> et
+ <literal>hilo</literal>, selon les possibilit�s offertes
par la base sous-jacente.
+ </para>
+ </sect3>
+ <sect3 id="mapping-declaration-id-assigned">
+ <title>Identifiants assign�s</title>
+ <para>
+ Si vous souhaitez que l'application assigne des identifiants (par
opposition
+ � la g�n�ration par Hibernate), vous pouvez utiliser le g�n�rateur
<literal>assigned</literal>.
+ Ce g�n�rateur sp�cial utilisera une valeur d'identifiant d�j�
utilis� par la propri�t� identifiant l'objet.
+ Ce g�n�rateur est utilis� quand la clef primaire est une clef
naturelle plut�t qu'une clef secondaire.
+ C'est le comportement par d�faut si vous ne pr�cisez pas
d'�l�ment <literal><generator></literal>.
+ </para>
+ <para>
+ Choisir le g�n�rateur <literal>assigned</literal> fait
utiliser
+ <literal>unsaved-value="undefined"</literal>
par Hibernate, le for�ant � interroger
+ la base pour d�terminer si l'instance est transiente ou d�tach�e,
� moins d'utiliser
+ une propri�t� version ou timestamp, ou alors de d�finir
+ <literal>Interceptor.isUnsaved()</literal>.
+ </para>
+ </sect3>
+ <sect3 id="mapping-declaration-id-select">
+ <title>Clefs primaires assign�es par trigger</title>
+ <para>
+ Pour les sch�mas de base h�rit�s d'anciens syst�mes uniquement
(Hibernate ne g�n�re pas de DDL avec des triggers)
+ </para>
+ <programlisting><![CDATA[<id name="id"
type="long" column="person_id">
+ <generator class="select">
+ <param name="key">socialSecurityNumber</param>
+ </generator>
+</id>]]></programlisting>
+ <para>
+ Dans l'exemple ci-dessus,
<literal>socialSecurityNumber</literal> a une
+ valeur unique d�finie par la classe en tant que clef naturelle et
<literal>person_id</literal>
+ est une clef secondaire dont la valeur est g�n�r�e par trigger.
+ </para>
+ </sect3>
+ </sect2>
+ <sect2 id="mapping-declaration-compositeid"
revision="3">
+ <title>composite-id</title>
+ <programlisting><![CDATA[<composite-id
+ name="propertyName"
+ class="ClassName"
+ mapped="true|false"
+ access="field|property|ClassName">
+ node="element-name|."
+
+ <key-property name="propertyName" type="typename"
column="column_name"/>
+ <key-many-to-one name="propertyName class="ClassName"
column="column_name"/>
+ ......
+</composite-id>]]></programlisting>
+ <para>
+ Pour une table avec clef compos�e, vous pouvez mapper plusieurs attributs
de la classe
+ comme propri�t�s identifiantes. L'�lement
<literal><composite-id></literal> accepte
+ les mappings de propri�t�s
<literal><key-property></literal> et les mappings
+ <literal><key-many-to-one></literal> comme
fils.
+ </para>
+ <programlisting><![CDATA[<composite-id>
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+ <para>
+ Vos classes persistantes <emphasis>doivent</emphasis>
surcharger les m�thodes <literal>equals()</literal>
+ et <literal>hashCode()</literal> pour impl�menter
l'�galit� d'identifiant compos�. Elles doivent aussi
+ implenter l'interface <literal>Serializable</literal>.
+ </para>
+ <para>
+ Malheureusement cette approche sur les identifiants compos�s signifie
qu'un objet persistant
+ est son propre identifiant. Il n'y a pas d'autre moyen pratique
de manipuler l'objet que par l'objet lui-m�me.
+ Vous devez instancier une instance de la classe persistante elle-m�me et
peupler ses attributs identifiants
+ avant de pouvoir appeler la m�thode <literal>load()</literal>
pour charger son �tat persistant associ�
+ � une clef compos�e. Nous appelons cette approche "identifiant
compos� <emphasis>embarqu�</emphasis>"
+ et ne la recommandons pas pour des applications complexes.
+ </para>
+
+ <para>
+ Une seconde approche, appel�e identifiant compos�
<emphasis>mapp�</emphasis>,
+ consiste � encapsuler les propri�t�s identifiantes (celles contenues dans
<literal><composite-id></literal>)
+ dans une classe particuli�re.
+ </para>
+
+ <programlisting><![CDATA[<composite-id
class="MedicareId" mapped="true">
+ <key-property name="medicareNumber"/>
+ <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+ <para>
+ Dans cet exemple, la classe d'identifiant
compos�e,<literal>MedicareId</literal> et la classe mapp�e elle-m�me,
+ poss�dent les propri�t�s <literal>medicareNumber</literal>
+ et <literal>dependent</literal>. La classe identifiante doit
red�finir
+ <literal>equals()</literal> et
<literal>hashCode()</literal> et impl�menter
+ <literal>Serializable</literal>. Le d�savantage de cette
approche est la
+ duplication du code.
+ </para>
+
+ <para>
+ Les attributs suivants servent � configurer un identifiant compos� mapp�
:
+ </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mapped</literal> (optionnel, d�faut �
<literal>false</literal>) :
+ indique qu'un identifiant compos� mapp� est utilis�, et que
les propri�t�s
+ contenues font r�f�rence aux deux classes (celle mapp�e et la
classe identifiante).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (optionnel, mais requis pour
un identifiant compos� mapp�) :
+ La classe composant utilis�e comme identifiant compos�.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Nous d�crirons une troisi�me approche beaucoup plus efficace ou
l'identifiant compos�
+ est impl�ment� comme une classe composant dans <xref
linkend="components-compositeid"/>.
+ Les attributs d�crits ci dessous, ne s'appliquent que pour cette
derni�re approche :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>name</literal> (optionnel, requis pour cette
approche) : une propri�t� de type
+ composant qui contient l'identifiant compos� (voir chapitre
9).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>access</literal> (optionnel - d�faut �
<literal>property</literal>) :
+ La strat�gie qu'Hibernate utilisera pour acc�der � la valeur
de la propri�t�.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>class</literal> (optionnel - d�faut au type
de la propri�t� d�termin� par r�flexion) :
+ La classe composant utilis�e comme identifiant (voir prochaine
section).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Cette derni�re approche est celle que nous recommandons pour toutes vos
applications.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-discriminator"
revision="3">
+ <title>discriminator</title>
+ <para>
+ L'�l�ment
<literal><discriminator></literal> est n�cessaire pour la
persistance polymorphique
+ qui utilise la strat�gie de mapping de table par hi�rarchie de classe.
La colonne discriminante contient
+ une valeur marqueur qui permet � la couche de persistance de savoir
quelle
+ sous-classe instancier pour une ligne particuli�re de table en base.
Un nombre restreint de types
+ peuvent �tre utilis�s :
+ <literal>string</literal>,
<literal>character</literal>, <literal>integer</literal>,
+ <literal>byte</literal>,
<literal>short</literal>, <literal>boolean</literal>,
+ <literal>yes_no</literal>,
<literal>true_false</literal>.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="discriminator1" coords="2 60"/>
+ <area id="discriminator2" coords="3 60"/>
+ <area id="discriminator3" coords="4 60"/>
+ <area id="discriminator4" coords="5 60"/>
+ <area id="discriminator5" coords="6 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<discriminator
+ column="discriminator_column"
+ type="discriminator_type"
+ force="true|false"
+ insert="true|false"
+ formula="arbitrary sql expression"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="discriminator1">
+ <para>
+ <literal>column</literal> (optionnel - par d�faut
� <literal>class</literal>) le
+ nom de la colonne discriminante.
+ </para>
+ </callout>
+ <callout arearefs="discriminator2">
+ <para>
+ <literal>type</literal> (optionnel - par d�faut �
<literal>string</literal>) un nom
+ indiquant le type Hibernate.
+ </para>
+ </callout>
+ <callout arearefs="discriminator3">
+ <para>
+ <literal>force</literal> (optionnel - par d�faut
� <literal>false</literal>)
+ "oblige" Hibernate � sp�cifier une valeur
discriminante autoris�e m�me quand on r�cup�re
+ toutes les instances de la classe de base.
+ </para>
+ </callout>
+ <callout arearefs="discriminator4">
+ <para>
+ <literal>insert</literal> (optionnel - par d�faut
� <literal>true</literal>)
+ � passer � <literal>false</literal> si la
colonne discriminante fait aussi partie
+ d'un identifiant compos� mapp� (Indique �
Hibernate de ne pas inclure la colonne
+ dans les <literal>INSERT</literal> SQL).
+ </para>
+ </callout>
+ <callout arearefs="discriminator5">
+ <para>
+ <literal>formula</literal> (optionnel) une
expression SQL arbitraire qui est ex�cut�e
+ quand un type doit �tre �valu�. Permet la discrimination
bas�e sur le contenu.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Les v�ritables valeurs de la colonne discriminante sont sp�cifi�es par
l'attribut
+ <literal>discriminator-value</literal> des �l�ments
<literal><class></literal> et
+ <literal><subclass></literal>.
+ </para>
+ <para>
+ L'attribut <literal>force</literal> n'est utile que
si la table contient des lignes avec des
+ valeurs "extra" discriminantes qui ne sont pas mapp�es � une
classe persistante. Ce ne sera g�n�ralement pas le cas.
+ </para>
+ <para>
+ En utilisant l'attribut <literal>formula</literal> vous
pouvez d�clarer une expression SQL arbitraire
+ qui sera utilis�e pour �valuer le type d'une ligne :
+ </para>
+ <programlisting><![CDATA[<discriminator
+ formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0
else 1 end"
+ type="integer"/>]]></programlisting>
+ </sect2>
+ <sect2 id="mapping-declaration-version" revision="4">
+ <title>version (optionnel)</title>
+ <para>
+ L'�l�ment <literal><version></literal>
est optionnel et indique que la table contient
+ des donn�es versionn�es. C'est particuli�rement utile si vous avez
l'intention d'utiliser
+ des <emphasis>transactions longues</emphasis> (voir
plus-bas).
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="version1" coords="2 60"/>
+ <area id="version2" coords="3 60"/>
+ <area id="version3" coords="4 60"/>
+ <area id="version4" coords="5 60"/>
+ <area id="version5" coords="6 60"/>
+ <area id="version6" coords="7 70"/>
+ <area id="version7" coords="8 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<version
+ column="version_column"
+ name="propertyName"
+ type="typename"
+ access="field|property|ClassName"
+ unsaved-value="null|negative|undefined"
+ generated="never|always"
+ insert="true|false"
+ node="element-name|@attribute-name|element/(a)attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="version1">
+ <para>
+ <literal>column</literal> (optionnel - par d�faut
�gal au nom de la propri�t�) : Le nom de la colonne
+ contenant le num�ro de version.
+ </para>
+ </callout>
+ <callout arearefs="version2">
+ <para>
+ <literal>name</literal> : Le nom d'un
attribut de la classe persistante.
+ </para>
+ </callout>
+ <callout arearefs="version3">
+ <para>
+ <literal>type</literal> (optionnel - par d�faut �
<literal>integer</literal>) :
+ Le type du num�ro de version.
+ </para>
+ </callout>
+ <callout arearefs="version4">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut
� <literal>property</literal>) : La strat�gie
+ � utiliser par Hibernate pour acc�der � la valeur de la
propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="version5">
+ <para>
+ <literal>unsaved-value</literal> (optionnel - par
d�faut � <literal>undefined</literal>) :
+ Une valeur de la propri�t� d'identifiant qui indique que
l'instance est nouvellement
+ instanci�e (non sauvegard�e), et qui la distingue des
instances d�tach�es qui ont
+ �t� sauvegard�es ou charg�es dans une session pr�c�dente
(<literal>undefined</literal> indique
+ que la valeur de l'atribut identifiant devrait �tre
utilis�).
+ </para>
+ </callout>
+ <callout arearefs="version6">
+ <para>
+ <literal>generated</literal> (optional - d�faut �
<literal>never</literal>) :
+ Indique que la valeur de la propri�t� version est g�n�r�e par
la base de donn�es
+ cf. <xref
linkend="mapping-generated">generated properties</xref>.
+ </para>
+ </callout>
+ <callout arearefs="version7">
+ <para>
+ <literal>insert</literal> (optionnel - d�faut �
<literal>true</literal>) :
+ Indique si la colonne de version doit �tre incluse dans les
ordres insert.
+ Peut �tre � <literal>false</literal> si et
seulement si la colonne de la
+ base de donn�es est d�finie avec une valeur par d�faut �
<literal>0</literal>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Les num�ros de version doivent avoir les types Hibernate
<literal>long</literal>, <literal>integer</literal>,
+ <literal>short</literal>,
<literal>timestamp</literal> ou <literal>calendar</literal>.
+ </para>
+ <para>
+ Une propri�t� de version ou un timestamp ne doit jamais �tre null pour
une instance
+ d�tach�e, ainsi Hibernate pourra d�tecter toute instance ayant une
version ou un timestamp null
+ comme transient, quelles que soient les strat�gies
<literal>unsaved-value</literal> sp�cifi�es.
+ <emphasis>D�clarer un num�ro de version ou un timestamp
"nullable" est un moyen pratique d'�viter
+ tout probl�me avec les r�attachements transitifs dans Hibernate,
particuli�rement utile pour ceux qui
+ utilisent des identifiants assign�s ou des clefs compos�es
!</emphasis>
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-timestamp" revision="3"
>
+ <title>timestamp (optionnel)</title>
+ <para>
+ L'�l�ment optionnel
<literal><timestamp></literal> indique que la table contient des
donn�es
+ horodat�es (timestamp). Cela sert d'alternative �
l'utilisation de num�ros de version. Les timestamps (ou horodatage)
+ sont par nature une impl�mentation moins fiable pour l'optimistic
locking. Cependant, l'application
+ peut parfois utiliser l'horodatage � d'autres fins.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="timestamp1" coords="2 45"/>
+ <area id="timestamp2" coords="3 45"/>
+ <area id="timestamp3" coords="4 45"/>
+ <area id="timestamp4" coords="5 45"/>
+ <area id="timestamp5" coords="6 70" />
+ <area id="timestamp6" coords="7 70" />
+ </areaspec>
+ <programlisting><![CDATA[<timestamp
+ column="timestamp_column"
+ name="propertyName"
+ access="field|property|ClassName"
+ unsaved-value="null|undefined"
+ source="vm|db"
+ generated="never|always"
+ node="element-name|@attribute-name|element/(a)attribute|."
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="timestamp1">
+ <para>
+ <literal>column</literal> (optionnel - par d�faut
� le nom de la propri�t�) : Le nom d'une colonne
+ contenant le timestamp.
+ </para>
+ </callout>
+ <callout arearefs="timestamp2">
+ <para>
+ <literal>name</literal> : Le nom d'une
propri�t� au sens JavaBean de type
+ <literal>Date</literal> ou
<literal>Timestamp</literal> de la classe persistante.
+ </para>
+ </callout>
+ <callout arearefs="timestamp3">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut
� <literal>property</literal>) : La strat�gie
+ � utiliser par Hibernate pour acc�der � la valeur de la
propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="timestamp4">
+ <para>
+ <literal>unsaved-value</literal> (optionnel - par
d�faut � <literal>null</literal>) :
+ Propri�t� dont la valeur est un num�ro de version qui
indique que l'instance est nouvellement
+ instanci�e (non sauvegard�e), et qui la distingue des
instances d�tach�es qui ont
+ �t� sauvegard�es ou charg�es dans une session pr�c�dente
(<literal>undefined</literal> indique
+ que la valeur de l'attribut identifiant devrait �tre
utilis�e).
+ </para>
+ </callout>
+ <callout arearefs="timestamp5">
+ <para>
+ <literal>source</literal> (optionnel - par d�faut
� <literal>vm</literal>) :
+ D'o� Hibernate doit-il r�cup�rer la valeur du timestamp?
Depuis la base de donn�es
+ ou depuis la JVM d'ex�cution? Les valeurs de timestamp de
la base de donn�es provoquent
+ une surcharge puisque Hibernate doit interroger la base pour
d�terminer la prochaine valeur
+ mais cela est plus s�r lorsque vous fonctionnez dans un
cluster. Remarquez aussi que
+ certains des dialectes ne supportent pas cette fonction, et
que d'autres l'impl�mentent
+ mal, provoquant des erreurs de pr�cision (Oracle 8 par
exemple).
+ </para>
+ </callout>
+ <callout arearefs="timestamp6">
+ <para>
+ <literal>generated</literal> (optional - d�faut �
<literal>never</literal>) :
+ Indique que la valeur de ce timestamp est g�n�r�e par la base
de donn�es
+ cf. <xref
linkend="mapping-generated">generated properties</xref>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Notez que <literal><timestamp></literal> est
�quivalent �
+ <literal><version
type="timestamp"></literal>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-property" revision="4">
+ <title>property</title>
+ <para>
+ L'�l�ment <literal><property></literal>
d�clare une propri�t� de la classe au sens JavaBean.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="property1" coords="2 45"/>
+ <area id="property2" coords="3 45"/>
+ <area id="property3" coords="4 45"/>
+ <areaset id="property4-5" coords="">
+ <area id="property4" coords="5 45"/>
+ <area id="property5" coords="6 45"/>
+ </areaset>
+ <area id="property6" coords="7 45"/>
+ <area id="property7" coords="8 45"/>
+ <area id="property8" coords="9 45"/>
+ <area id="property9" coords="10 45"/>
+ <area id="property10" coords="11 45"/>
+ <area id="property11" coords="12 45"/>
+ <area id="property12" coords="13 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<property
+ name="propertyName"
+ column="column_name"
+ type="typename"
+ update="true|false"
+ insert="true|false"
+ formula="arbitrary SQL expression"
+ access="field|property|ClassName"
+ lazy="true|false"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ generated="never|insert|always"
+ node="element-name|@attribute-name|element/(a)attribute|."
+ index="index_name"
+ unique_key="unique_key_id"
+ length="L"
+ precision="P"
+ scale="S"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="property1">
+ <para>
+ <literal>name</literal> : nom de la propri�t�,
avec une lettre initiale en minuscule.
+ </para>
+ </callout>
+ <callout arearefs="property2">
+ <para>
+ <literal>column</literal> (optionnel - par d�faut
au nom de la propri�t�) : le nom
+ de la colonne mapp�e. Cela peut aussi �tre indiqu�
dans le(s) sous-�l�ment(s)
+ <literal><column></literal>.
+ </para>
+ </callout>
+ <callout arearefs="property3">
+ <para>
+ <literal>type</literal> (optionnel) : nom
indiquant le type Hibernate.
+ </para>
+ </callout>
+ <callout arearefs="property4-5">
+ <para>
+ <literal>update, insert</literal> (optionnel -
par d�faut � <literal>true</literal>) :
+ indique que les colonnes mapp�es devraient �tre incluses dans
des <literal>UPDATE</literal> SQL
+ et/ou des <literal>INSERT</literal>. Mettre les
deux � <literal>false</literal>
+ emp�che la propagation en base de donn�es (utile si vous savez
qu'un trigger affectera la valeur � la colonne).
+ </para>
+ </callout>
+ <callout arearefs="property6">
+ <para>
+ <literal>formula</literal> (optionnel) : une
expression SQL qui d�finit la valeur pour une propri�t�
+ <emphasis>calcul�e</emphasis>. Les propri�t�s
calcul�es ne poss�de pas leur propre mapping.
+ </para>
+ </callout>
+ <callout arearefs="property7">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut
� <literal>property</literal>): Strat�gie que Hibernate
+ doit utiliser pour acc�der � cette valeur.
+ </para>
+ </callout>
+ <callout arearefs="property8">
+ <para>
+ <literal>lazy</literal> (optionnel - par d�faut �
<literal>false</literal>): Indique
+ que cette propri�t� devrait �tre charg�e en diff�r� (lazy
loading) quand on acc�de � la variable
+ d'instance pour la premi�re fois.
+ </para>
+ </callout>
+ <callout arearefs="property9">
+ <para>
+ <literal>unique</literal> (optionnel): G�n�re le
DDL d'une contrainte d'unicit� pour les colonnes.
+ Permet aussi d'en faire la cible d'un
<literal>property-ref</literal>.
+ </para>
+ </callout>
+ <callout arearefs="property10">
+ <para>
+ <literal>not-null</literal> (optionnel): G�n�re
le DDL d'une contrainte de non nullit� pour les colonnes.
+ </para>
+ </callout>
+ <callout arearefs="property11">
+ <para>
+ <literal>optimistic-lock</literal> (optionnel -
par d�faut � <literal>true</literal>):
+ Indique que les mises � jour de cette propri�t� peuvent ou
non n�cessiter l'acquisition
+ d'un verrou optimiste. En d'autres termes, cela
d�termine s'il est n�cessaire d'incr�menter
+ un num�ro de version quand cette propri�t� est marqu�e
obsol�te (dirty).
+ </para>
+ </callout>
+ <callout arearefs="property12">
+ <para>
+ <literal>generated</literal> (optional - d�faut
�<literal>never</literal>):
+ Indique que la valeur de ce timestamp est g�n�r�e par la base
de donn�es
+ cf. <xref
linkend="mapping-generated">generated properties</xref>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ <emphasis>typename</emphasis> peut �tre:
+ </para>
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Nom d'un type basique Hibernate (ex: <literal>integer,
string, character,
+ date, timestamp, float, binary, serializable, object,
blob</literal>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Nom d'une classe Java avec un type basique par d�faut (ex:
<literal>int, float,
+ char, java.lang.String, java.util.Date, java.lang.Integer,
java.sql.Clob</literal>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Nom d'une classe Java s�rialisable.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Nom d'une classe ayant un type sp�cifique (ex:
<literal>com.illflow.type.MyCustomType</literal>).
+ </para>
+ </listitem>
+ </orderedlist>
+ <para>
+ Si vous n'indiquez pas un type, Hibernate utlisera la r�flexion
sur le nom de la propri�t�
+ pour tenter de trouver le type Hibernate correct. Hibernate essayera
d'interpr�ter
+ le nom de la classe retourn�e par le getter de la propri�t� en
utilisant les r�gles 2, 3,
+ 4 dans cet ordre. Cependant, ce n'est pas toujours suffisant. Dans
certains cas vous aurez
+ encore besoin de l'attribut <literal>type</literal>
(Par exemple, pour distinguer
+ <literal>Hibernate.DATE</literal> et
<literal>Hibernate.TIMESTAMP</literal>, ou pour pr�ciser
+ un type sp�cifique).
+ </para>
+ <para>
+ L'attribut <literal>access</literal> permet de
contr�ler comment Hibernate acc�dera
+ � la propri�t� � l'ex�cution. Par d�faut, Hibernate utilisera les
m�thodes set/get.
+ Si vous indiquez
<literal>access="field"</literal>, Hibernate ignorera les
getter/setter
+ et acc�dera � la propri�t� directement en utilisant la r�flexion. Vous
pouvez sp�cifier
+ votre propre strat�gie d'acc�s aux propri�t� en donnant une classe
qui impl�mente l'interface
+ <literal>org.hibernate.property.PropertyAccessor</literal>.
+ </para>
+ <para>
+ Une fonctionnalit� particuli�rement int�ressante est les propri�t�s
d�riv�es.
+ Ces propri�t�s sont par d�finition en lecture seule, la valeur de la
propri�t� est calcul�e au chargement.
+ Le calcul est d�clar� comme une expression SQL, qui se traduit par une
sous-requ�te <literal>SELECT</literal>
+ dans la requ�te SQL qui charge une instance :
+ </para>
+ <programlisting><![CDATA[
+<property name="totalPrice"
+ formula="( SELECT SUM (li.quantity*p.price) FROM LineItem li, Product p
+ WHERE li.productId = p.productId
+ AND li.customerId = customerId
+ AND li.orderNumber = orderNumber
)"/>]]></programlisting>
+ <para>
+ Remarquez que vous pouvez r�f�rencer la propre table des entit�s en ne
d�clarant pas un
+ alias sur une colonne particuli�re
(<literal>customerId</literal> dans l'exemple donn�).
+ Notez aussi que vous pouvez utiliser le sous-�l�ment de mapping
<literal><formula></literal>
+ plut�t que d'utiliser l'attribut si vous le souhaitez.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-manytoone"
revision="5">
+ <title>many-to-one</title>
+ <para> Une association ordinaire vers une autre classe persistante est
d�clar�e en utilisant
+ un �l�ment <literal>many-to-one</literal>. Le mod�le
relationnel est une association
+ de type many-to-one : une clef �trang�re dans une table r�f�rence la
ou les clef(s) primaire(s) dans la table cible.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="manytoone1" coords="2 60"/>
+ <area id="manytoone2" coords="3 60"/>
+ <area id="manytoone3" coords="4 60"/>
+ <area id="manytoone4" coords="5 60"/>
+ <area id="manytoone5" coords="6 60"/>
+ <areaset id="manytoone6-7" coords="">
+ <area id="manytoone6" coords="7 60"/>
+ <area id="manytoone7" coords="8 60"/>
+ </areaset>
+ <area id="manytoone8" coords="9 60"/>
+ <area id="manytoone9" coords="10 60"/>
+ <area id="manytoone10" coords="11 60"/>
+ <area id="manytoone11" coords="12 60"/>
+ <area id="manytoone12" coords="13 60"/>
+ <area id="manytoone13" coords="14 60"/>
+ <area id="manytoone14" coords="15 60"/>
+ <area id="manytoone14" coords="15 70"/>
+ <area id="manytoone15" coords="16 70"/>
+ <area id="manytoone16" coords="17 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-one
+ name="propertyName"
+ column="column_name"
+ class="ClassName"
+ cascade="cascade_style"
+ fetch="join|select"
+ update="true|false"
+ insert="true|false"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ unique="true|false"
+ not-null="true|false"
+ optimistic-lock="true|false"
+ lazy="proxy|no-proxy|false"
+ not-found="ignore|exception"
+ entity-name="EntityName"
+ formula="arbitrary SQL expression"
+ node="element-name|@attribute-name|element/(a)attribute|."
+ embed-xml="true|false"
+ index="index_name"
+ unique_key="unique_key_id"
+ foreign-key="foreign_key_name"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytoone1">
+ <para>
+ <literal>name</literal> : Nom de la propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="manytoone2">
+ <para>
+ <literal>column</literal> (optionnel) : Le nom de
la clef �trang�re. Cela peut �tre
+ aussi indiqu� avec le sous-�l�ment
<literal><column></literal>.
+ </para>
+ </callout>
+ <callout arearefs="manytoone3">
+ <para>
+ <literal>class</literal> (optionnel - par d�faut
le type de la propri�t� d�termin�
+ par r�flexion) : Le nom de la classe associ�e.
+ </para>
+ </callout>
+ <callout arearefs="manytoone4">
+ <para>
+ <literal>cascade</literal> (optionnel) : Indique
quelles op�rations doivent
+ �tre propag�es de l'objet p�re vers les objets associ�s.
+ </para>
+ </callout>
+ <callout arearefs="manytoone5">
+ <para>
+ <literal>fetch</literal> (optionnel - par d�faut
� <literal>select</literal>) :
+ Choisit entre le chargement de type outer-join ou le
chargement par select successifs.
+ </para>
+ </callout>
+ <callout arearefs="manytoone6-7">
+ <para>
+ <literal>update, insert</literal> (optionnel -
par d�faut � <literal>true</literal>) :
+ indique que les colonnes mapp�es devraient �tre incluses dans
des <literal>UPDATE</literal> SQL
+ et/ou des <literal>INSERT</literal>. Mettre les
deux � <literal>false</literal>
+ emp�che la propagation en base de donn�es (utile si vous savez
qu'un trigger affectera la valeur � la colonne).
+ </para>
+ </callout>
+ <callout arearefs="manytoone8">
+ <para>
+ <literal>property-ref</literal> : (optionnel) Le
nom d'une propri�t� de la classe
+ associ�e qui est li�e � cette clef �trang�re. Si ce n'est
pas sp�cifi�, la clef primaire de la
+ classe associ�e est utilis�e.
+ </para>
+ </callout>
+ <callout arearefs="manytoone9">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut
� <literal>property</literal>) : La
+ strat�gie � utiliser par Hibernate pour acc�der � la valeur
de cette propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="manytoone10">
+ <para>
+ <literal>unique</literal> (optionnel) : G�n�re le
DDL d'une contrainte d'unicit� pour la clef �trang�re.
+ Permet aussi d'en faire la cible d'un
<literal>property-ref</literal>. Cela permet de cr�er une v�ritable
+ association one-to-one.
+ </para>
+ </callout>
+ <callout arearefs="manytoone11">
+ <para>
+ <literal>not-null</literal> (optionnel) : G�n�re
le DDL pour une contrainte de non nullit� pour la clef �trang�re.
+ </para>
+ </callout>
+ <callout arearefs="manytoone12">
+ <para>
+ <literal>optimistic-lock</literal> (optionnel -
par d�faut � <literal>true</literal>) :
+ Indique que les mises � jour de cette propri�t� requi�rent ou
non l'acquisition
+ d'un verrou optimiste. En d'autres termes, d�termine
si un incr�ment de version doit
+ avoir lieu quand la propri�t� est marqu�e obsol�te (dirty).
+ </para>
+ </callout>
+ <callout arearefs="manytoone13">
+ <para>
+ <literal>lazy</literal> (optionnel - par d�faut �
<literal>false</literal>) : Indique
+ que cette propri�t� doit �tre charg�e en diff�r� (lazy
loading) au premier acc�s
+ � la variable d'instance (n�cessite une instrumentation
du bytecode lors de la phase
+ de construction). Remarquez que cela n'influence pas le
comportement du proxy
+ Hibernate - comme l'attribut
<literal>lazy</literal> sur des classes ou des mappings
+ de collections, mais utilise l'interception pour le
chargement diff�r�.
+ <literal>lazy="false"</literal> indique
que l'association sera toujours charg�e.
+ </para>
+ </callout>
+ <callout arearefs="manytoone14">
+ <para>
+ <literal>not-found</literal> (optionnel - par
d�faut � <literal>exception</literal>) :
+ Indique comment les clefs �trang�res qui r�f�rencent des
lignes manquantes doivent �tre manipul�es :
+ <literal>ignore</literal> traitera une ligne
manquante comme une association nulle.
+ </para>
+ </callout>
+ <callout arearefs="manytoone15">
+ <para>
+ <literal>entity-name</literal> (optionnel) : Le
nom de l'entit� de la classe associ�e.
+ </para>
+ </callout>
+ <callout arearefs="manytoone16">
+ <para>
+ <literal>formula</literal> (optionnel) : une
expression SQL qui d�finit la valeur
+ pour une cl� �trang�re calcul�e.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Donner une valeur significative � l'attribut
<literal>cascade</literal> autre que
+ <literal>none</literal> propagera certaines op�rations �
l'objet associ�. Les valeurs
+ significatives sont les noms des op�rations Hibernate basiques,
+ <literal>persist, merge, delete, save-update, evict, replicate,
lock,
+ refresh</literal>, ainsi que les valeurs sp�ciales
<literal>delete-orphan</literal>
+ et <literal>all</literal> et des combinaisons de noms
d'op�rations s�par�es par des virgules,
+ comme par exemple
<literal>cascade="persist,merge,evict"</literal> ou
+ <literal>cascade="all,delete-orphan"</literal>.
Voir <xref linkend="objectstate-transitive"/>
+ pour une explication compl�te.
+ Notez que les assocations many-to-one et one-to-one ne supportent pas
orphan delete.
+ </para>
+
+ <para>
+ Une d�claration <literal>many-to-one</literal> typique est
aussi simple que :
+ </para>
+ <programlisting><![CDATA[<many-to-one name="product"
class="Product" column="PRODUCT_ID"/>]]></programlisting>
+ <para>
+ L'attribut <literal>property-ref</literal> devrait �tre
utilis� pour mapper seulement des donn�es
+ provenant d'un ancien syst�me o� les clefs �trang�res font r�f�rence
� une clef unique de la table associ�e
+ et qui n'est pas la clef primaire. C'est un cas de mauvaise
conception relationnelle.
+ Par exemple, supposez que la classe
<literal>Product</literal> a un num�ro de s�rie unique qui n'est pas
+ la clef primaire. (L'attribut <literal>unique</literal>
contr�le la g�n�ration DDL par Hibernate avec
+ l'outil SchemaExport.)
+ </para>
+ <programlisting><![CDATA[<property name="serialNumber"
unique="true" type="string"
column="SERIAL_NUMBER"/>]]></programlisting>
+ <para>
+ Ainsi le mapping pour <literal>OrderItem</literal> peut
utiliser :
+ </para>
+ <programlisting><![CDATA[<many-to-one name="product"
property-ref="serialNumber"
column="PRODUCT_SERIAL_NUMBER"/>]]></programlisting>
+ <para>
+ bien que ce ne soit certainement pas encourag�.
+ </para>
+ <para>
+ Si la clef unique r�f�renc�e comprend des propri�t�s multiples de
l'entit� associ�e, vous devez mapper
+ ces propri�t�s � l'int�rieur d'un �l�ment
<literal><properties></literal>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-onetoone" revision="3">
+ <title>one-to-one</title>
+ <para>
+ Une association one-to-one vers une autre classe persistante est d�clar�e
avec l'�l�ment
+ <literal>one-to-one</literal>.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="onetoone1" coords="2 60"/>
+ <area id="onetoone2" coords="3 60"/>
+ <area id="onetoone3" coords="4 60"/>
+ <area id="onetoone4" coords="5 60"/>
+ <area id="onetoone5" coords="6 60"/>
+ <area id="onetoone6" coords="7 60"/>
+ <area id="onetoone7" coords="8 60"/>
+ <area id="onetoone8" coords="9 60"/>
+ <area id="onetoone9" coords="10 70"/>
+ <area id="onetoone10" coords="11 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-one
+ name="propertyName"
+ class="ClassName"
+ cascade="cascade_style"
+ constrained="true|false"
+ fetch="join|select"
+ property-ref="propertyNameFromAssociatedClass"
+ access="field|property|ClassName"
+ formula="any SQL expression"
+ entity-name="EntityName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetoone1">
+ <para>
+ <literal>name</literal> : Le nom de la
propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="onetoone2">
+ <para>
+ <literal>class</literal> (optionnel - par d�faut
du type de la propri�t�
+ d�termin� par r�flexion) : Le nom de la classe associ�e.
+ </para>
+ </callout>
+ <callout arearefs="onetoone3">
+ <para>
+ <literal>cascade</literal> (optionnel) : Indique
quelles op�rations doivent
+ �tre cascad�es de l'objet p�re vers l'objet associ�.
+ </para>
+ </callout>
+ <callout arearefs="onetoone4">
+ <para>
+ <literal>constrained</literal> (optionnel) :
Indique qu'une contrainte de clef �trang�re
+ sur la clef primaire de la table mapp�e r�f�rence la table de
la classe associ�e.
+ Cette option affecte l'ordre dans lequel chaque
<literal>save()</literal> et chaque
+ <literal>delete()</literal> sont cascad�s et
d�termine si l'association peut utiliser un proxy
+ (aussi utilis� par l'outil d'export de sch�ma).
+ </para>
+ </callout>
+ <callout arearefs="onetoone5">
+ <para>
+ <literal>fetch</literal> (optionnel - par d�faut
� <literal>select</literal>) :
+ Choisit entre r�cup�ration par jointure externe ou select
s�quentiel.
+ </para>
+ </callout>
+ <callout arearefs="onetoone6">
+ <para>
+ <literal>property-ref</literal> (optionnel) : Le
nom de la propri�t� de la classe associ�e qui est jointe � la clef
+ primaire de cette classe. Si ce n'est pas sp�cifi�, la
clef primaire de la classe associ�e est utilis�e.
+ </para>
+ </callout>
+ <callout arearefs="onetoone7">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut
� <literal>property</literal>) :
+ La strat�gie � utiliser par Hibernate pour acc�der � la
valeur de la propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="onetoone8">
+ <para>
+ <literal>formula</literal> (optionnel) : Presque
toutes les associations one-to-one pointent sur la clef primaire
+ de l'entit� propri�taire. Dans les rares cas diff�rents,
vous devez donner une ou plusieurs
+ autres colonnes ou expression � joindre par une formule SQL
(voir <literal>org.hibernate.test.onetooneformula</literal> pour un exemple).
+ </para>
+ </callout>
+ <callout arearefs="onetoone9">
+ <para>
+ <literal>lazy</literal> (optionnel - par d�faut
<literal>proxy</literal>) :
+ Par d�faut, les associations simples sont soumise � proxy.
<literal>lazy="no-proxy"</literal>
+ sp�cifie que la propri�t� doit �tre charg�e � la demande au
premier acc�s � l'instance.
+ (n�cessite l'intrumentation du bytecode � la
construction).
+ <literal>lazy="false"</literal> indique
que l'association sera toujours charg�e
+ agressivement. <emphasis>Notez que si
<literal>constrained="false"</literal>,
+ l'utilisation de proxy est impossible et Hibernate
chargera automatiquement l'association !</emphasis>
+ </para>
+ </callout>
+ <callout arearefs="onetoone10">
+ <para>
+ <literal>entity-name</literal> (optional) : The
entity name of the associated class.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Il existe deux types d'associations one-to-one :
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ associations par clef primaire
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ association par clef �trang�re unique
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Les associations par clef primaire ne n�cessitent pas une colonne
suppl�mentaire en table ; si deux lignes sont
+ li�s par l'association alors les deux lignes de la table partagent la
m�me valeur de clef primaire. Donc si vous
+ voulez que deux objets soient li�s par une association par clef primaire,
vous devez faire en sorte qu'on leur
+ assigne la m�me valeur d'identifiant !
+ </para>
+ <para>
+ Pour une association par clef primaire, ajoutez les mappings suivants �
<literal>Employee</literal> et
+ <literal>Person</literal>, respectivement.
+ </para>
+ <programlisting><![CDATA[<one-to-one name="person"
class="Person"/>]]></programlisting>
+ <programlisting><![CDATA[<one-to-one name="employee"
class="Employee" constrained="true"/>]]></programlisting>
+ <para>
+ Maintenant, vous devez faire en sorte que les clefs primaires des lignes
li�es dans les tables PERSON et EMPLOYEE
+ sont �gales. On utilise une strat�gie Hibernate sp�ciale de g�n�ration
d'identifiants appel�e
+ <literal>foreign</literal> :
+ </para>
+ <programlisting><![CDATA[<class name="person"
table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="foreign">
+ <param name="property">employee</param>
+ </generator>
+ </id>
+ ...
+ <one-to-one name="employee"
+ class="Employee"
+ constrained="true"/>
+</class>]]></programlisting>
+ <para>
+ Une instance fra�chement enregistr�e de
<literal>Person</literal> se voit alors assign�e la m�me valeur
+ de clef primaire que l'instance de
<literal>Employee</literal> r�f�renc�e par la propri�t�
<literal>employee</literal>
+ de cette <literal>Person</literal>.
+ </para>
+ <para>
+ Alternativement, une clef �trang�re avec contrainte d'unicit� de
<literal>Employee</literal> vers
+ <literal>Person</literal> peut �tre indiqu�e ainsi :
+ </para>
+ <programlisting><![CDATA[<many-to-one name="person"
class="Person" column="PERSON_ID"
unique="true"/>]]></programlisting>
+ <para>
+ Et cette association peut �tre rendue bidirectionnelle en ajoutant ceci
au mapping de <literal>Person</literal> :
+ </para>
+ <programlisting><![CDATA[<one-to-one name="employee"
class="Employee"
property-ref="person"/>]]></programlisting>
+ </sect2>
+
+ <sect2 id="mapping-declaration-naturalid">
+ <title>natural-id</title>
+
+ <programlisting><![CDATA[<natural-id
mutable="true|false"/>
+ <property ... />
+ <many-to-one ... />
+ ......
+</natural-id>]]></programlisting>
+
+ <para>
+ Bien que nous recommandions l'utilisation de cl� primaire g�n�r�e,
vous devriez toujours
+ essayer d'identifier des cl� m�tier (naturelles) pour toutes vos
entit�s. Une cl� naturelle
+ est une propri�t� ou une combinaison de propri�t�s uniques et non nulles.
Si elle est aussi
+ immuable, c'est encore mieux. Mappez les propri�t�s de la cl�
naturelle dans l'�l�ment
+ <literal><natural-id></literal>. Hibernate
g�n�rera la cl� unique n�cessaire et les contraintes
+ de non-nullit�, et votre mapping s'auto-documentera.
+ </para>
+
+ <para>
+ Nous vous recommandons fortement d'impl�menter
<literal>equals()</literal> et
+ <literal>hashCode()</literal> pour comparer les cl�s
naturelles de l'entit�.
+ </para>
+
+ <para>
+ Ce mapping n'est pas destin� � �tre utilis� avec des entit�s qui ont
des cl�s naturelles.
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>mutable</literal> (optionel, par d�faut �
<literal>false</literal>) :
+ Par d�faut, les identifiants naturels sont suppos�s �tre immuable
(constants).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+ <sect2 id="mapping-declaration-component"
revision="2">
+ <title>component, dynamic-component</title>
+ <para>
+ L'�l�ment <literal><component></literal>
mappe les propri�t�s d'un objet fils
+ aux colonnes d'une classe parente. Les composants peuvent en retour
d�clarer leurs propres
+ propri�t�s, composants ou collections. Voir "Components" plus
bas.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="component1" coords="2 45"/>
+ <area id="component2" coords="3 45"/>
+ <area id="component3" coords="4 45"/>
+ <area id="component4" coords="5 45"/>
+ <area id="component5" coords="6 45"/>
+ <area id="component6" coords="7 45"/>
+ <area id="component7" coords="8 45"/>
+ <area id="component8" coords="9 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<component
+ name="propertyName"
+ class="className"
+ insert="true|false"
+ update="true|false"
+ access="field|property|ClassName"
+ lazy="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</component>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="component1">
+ <para>
+ <literal>name</literal> : Nom de la propri�t�
+ </para>
+ </callout>
+ <callout arearefs="component2">
+ <para>
+ <literal>class</literal> (optionnel - par d�faut
au type de la propri�t� d�termin� par r�flexion) :
+ le nom de la classe (fille) du composant.
+ </para>
+ </callout>
+ <callout arearefs="component3">
+ <para>
+ <literal>insert</literal> : Est ce que les
colonnes mapp�es apparaissent dans les
+ <literal>INSERT</literal>s ?
+ </para>
+ </callout>
+ <callout arearefs="component4">
+ <para>
+ <literal>update</literal>: Est ce que les
colonnes mapp�es apparaissent dans les
+ <literal>UPDATE</literal>s ?
+ </para>
+ </callout>
+ <callout arearefs="component5">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut
� <literal>property</literal>) :
+ La strat�gie que Hibernate doit utiliser pour acc�der � la
valeur de cette propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="component6">
+ <para>
+ <literal>lazy</literal> (optionnel - par d�faut �
<literal>false</literal>) :
+ Indique que ce composant doit �tre charg� au premier acc�s
+ � la variable d'instance (n�cessite une instrumentation
du bytecode au moment du build).
+ </para>
+ </callout>
+ <callout arearefs="component7">
+ <para>
+ <literal>optimistic-lock</literal> (optionnel -
par d�faut � <literal>true</literal>) :
+ Indique que les mises � jour sur ce composant n�cessitent
ou non l'acquisition d'un
+ verrou optimiste. En d'autres termes, cela d�termine
si une incr�mentation de version
+ doit avoir lieu quand la propri�t� est marqu�e obsol�te
(dirty).
+ </para>
+ </callout>
+ <callout arearefs="component8">
+ <para>
+ <literal>unique</literal> (optionnel - par d�faut
� <literal>false</literal>) :
+ Indique qu'une contrainte d'unicit� existe sur
toutes les colonnes mapp�es de ce composant.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Les tags fils <literal><property></literal>
mappent les propri�t�s
+ de la classe fille sur les colonnes de la table.
+ </para>
+ <para>
+ L'�l�ment <literal><component></literal>
permet de d�clarer sous-�l�ment <literal><parent></literal> qui
associe une propri�t�
+ de la classe composant comme une r�f�rence arri�re vers l'entit�
contenante.
+ </para>
+ <para>
+ L'�l�ment
<literal><dynamic-component></literal> permet � une
<literal>Map</literal> d'�tre mapp�e
+ comme un composant, quand les noms de la propri�t� font r�f�rence aux
clefs de cette Map, voir
+ <xref linkend="components-dynamic"/>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-properties"
revision="2">
+ <title>properties</title>
+ <para>
+ L'�l�ment <literal><properties></literal>
permet la d�finition d'un groupement logique nomm�
+ des propri�t�s d'une classe. L'utilisation la plus importante de
cette construction est la possibilit�
+ pour une combinaison de propri�t�s d'�tre la cible d'un
<literal>property-ref</literal>. C'est aussi
+ un moyen pratique de d�finir une contrainte d'unicit�
multi-colonnes.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="properties1" coords="2 45"/>
+ <area id="properties2" coords="3 45"/>
+ <area id="properties3" coords="4 45"/>
+ <area id="properties4" coords="5 45"/>
+ <area id="properties5" coords="6 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<properties
+ name="logicalName"
+ insert="true|false"
+ update="true|false"
+ optimistic-lock="true|false"
+ unique="true|false"
+>
+
+ <property ...../>
+ <many-to-one .... />
+ ........
+</properties>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="properties1">
+ <para>
+ <literal>name</literal> : Le nom logique d'un
regroupement et
+ <emphasis>non</emphasis> le v�ritable nom
d'une propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="properties2">
+ <para>
+ <literal>insert</literal> : Est-ce que les
colonnes mapp�es apparaissent dans les
+ <literal>INSERT</literal>s ?
+ </para>
+ </callout>
+ <callout arearefs="properties3">
+ <para>
+ <literal>update</literal> : Est-ce que les
colonnes mapp�es apparaissent dans les
+ <literal>UPDATE</literal>s ?
+ </para>
+ </callout>
+ <callout arearefs="properties4">
+ <para>
+ <literal>optimistic-lock</literal> (optionnel -
par d�faut � <literal>true</literal>) :
+ Indique que les mises � jour sur ce composant n�cessitent
ou non l'acquisition d'un
+ verrou optimiste. En d'autres termes, cela d�termine
si une incr�mentation
+ de version doit avoir lieu quand la propri�t� est marqu�e
obsol�te (dirty).
+ </para>
+ </callout>
+ <callout arearefs="properties5">
+ <para>
+ <literal>unique</literal> (optionnel - par d�faut
� <literal>false</literal>) :
+ Indique qu'une contrainte d'unicit� existe sur toutes
les colonnes mapp�es de ce composant.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Par exemple, si nous avons le mapping de
<literal><properties></literal> suivant :
+ </para>
+ <programlisting><![CDATA[<class name="Person">
+ <id name="personNumber"/>
+ ...
+ <properties name="name"
+ unique="true" update="false">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </properties>
+</class>]]></programlisting>
+ <para>
+ Alors nous pourrions avoir une association sur des donn�es d'un
ancien syst�me (legacy) qui font r�f�rence
+ � cette clef unique de la table <literal>Person</literal> au
lieu de la clef primaire :
+ </para>
+ <programlisting><![CDATA[<many-to-one name="person"
+ class="Person" property-ref="name">
+ <column name="firstName"/>
+ <column name="initial"/>
+ <column name="lastName"/>
+</many-to-one>]]></programlisting>
+ <para>
+ Nous ne recommandons pas l'utilisation de ce genre de chose en dehors
du contexte de mapping de donn�es h�rit�es
+ d'anciens syst�mes.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-subclass" revision="4">
+ <title>subclass</title>
+ <para>
+ Pour finir, la persistance polymorphique n�cessite la d�claration de
chaque sous-classe de la classe persistante de base.
+ pour la strat�gie de mapping de type table-per-class-hierarchy, on
utilise la d�claration
+ <literal><subclass></literal>.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="subclass1" coords="2 55"/>
+ <area id="subclass2" coords="3 55"/>
+ <area id="subclass3" coords="4 55"/>
+ <area id="subclass4" coords="5 55"/>
+ </areaspec>
+ <programlisting><![CDATA[<subclass
+ name="ClassName"
+ discriminator-value="discriminator_value"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ entity-name="EntityName"
+ node="element-name"
+ extends="SuperclassName">
+
+ <property .... />
+ .....
+</subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="subclass1">
+ <para>
+ <literal>name</literal> : Le nom complet de la
sous-classe.
+ </para>
+ </callout>
+ <callout arearefs="subclass2">
+ <para>
+ <literal>discriminator-value</literal> (optionnel
- par d�faut le nom de la classe) :
+ une valeur qui distingue les diff�rentes sous-classes.
+ </para>
+ </callout>
+ <callout arearefs="subclass3">
+ <para>
+ <literal>proxy</literal> (optionnel) : Indique
une classe ou interface � utiliser pour les chargements
+ � la demande des proxies (lazy).
+ </para>
+ </callout>
+ <callout arearefs="subclass4">
+ <para>
+ <literal>lazy</literal> (optionnel, par d�faut �
<literal>true</literal>) : Sp�cifier
+ <literal>lazy="false"</literal>
d�sactive l'utilisation du chargement � la demande (lazy).
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Chaque sous-classe devrait d�clarer ses propres propri�t�s persistantes
et sous-classes.
+ Les propri�t�s <literal><version></literal> et
<literal><id></literal>
+ sont implicitement h�rit�s de la classe de base. Chaque sous-classe dans
une hi�rarchie doit
+ d�finir une unique <literal>discriminator-value</literal>. Si
aucune n'est sp�cifi�e,
+ le nom complet de la classe Java est utilis�.
+ </para>
+ <para>
+ Pour plus d'infos sur le mapping d'h�ritage, voir <xref
linkend="inheritance"/>.
+ </para>
+ <programlisting><![CDATA[
+<hibernate-mapping>
+ <subclass name="DomesticCat" extends="Cat"
discriminator-value="D">
+ <property name="name" type="string"/>
+ </subclass>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ Pour des informations sur les mappings d'h�ritage, voir <xref
linkend="inheritance"/>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-joinedsubclass"
revision="3">
+ <title>joined-subclass</title>
+ <para>
+ Une autre fa�on possible de faire est la suivante, chaque sous-classe
peut �tre mapp�e vers sa propre table (strat�gie
+ de mapping de type table-per-subclass). L'�tat h�rit� est r�cup�r� en
joignant la table de la super-classe.
+ L'�l�ment
<literal><joined-subclass></literal> est utilis�.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="joinedsubclass1" coords="2 45"/>
+ <area id="joinedsubclass2" coords="3 45"/>
+ <area id="joinedsubclass3" coords="4 45"/>
+ <area id="joinedsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<joined-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName">
+
+ <key .... >
+
+ <property .... />
+ .....
+</joined-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="joinedsubclass1">
+ <para>
+ <literal>name</literal> : Le nom Java complet de
la sous-classe.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass2">
+ <para>
+ <literal>table</literal> : Le nom de la table de
la sous-classe.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass3">
+ <para>
+ <literal>proxy</literal> (optionnel) : Indique
une classe ou interface pour le chargement diff�r� des proxies.
+ </para>
+ </callout>
+ <callout arearefs="joinedsubclass4">
+ <para>
+ <literal>lazy</literal> (optionnel, par d�faut �
<literal>true</literal>) : Indiquer
+ <literal>lazy="false"</literal>
d�sactive l'utilisation du chargement � la demande.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Aucune colonne discriminante n'est n�cessaire pour cette strat�gie de
mapping. Cependant,
+ chaque sous-classe doit d�clarer une colonne de table contenant
l'objet identifiant qui utilise l'�l�ment
+ <literal><key></literal>. Le mapping au d�but
de ce chapitre serait r�-�crit ainsi :
+ </para>
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class name="Cat" table="CATS">
+ <id name="id" column="uid"
type="long">
+ <generator class="hilo"/>
+ </id>
+ <property name="birthdate" type="date"/>
+ <property name="color" not-null="true"/>
+ <property name="sex" not-null="true"/>
+ <property name="weight"/>
+ <many-to-one name="mate"/>
+ <set name="kittens">
+ <key column="MOTHER"/>
+ <one-to-many class="Cat"/>
+ </set>
+ <joined-subclass name="DomesticCat"
table="DOMESTIC_CATS">
+ <key column="CAT"/>
+ <property name="name" type="string"/>
+ </joined-subclass>
+ </class>
+
+ <class name="eg.Dog">
+ <!-- mapping for Dog could go here -->
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+ <para>
+ Pour des informations sur les mappings d'h�ritage, voir <xref
linkend="inheritance"/>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-unionsubclass"
revision="2">
+ <title>union-subclass</title>
+ <para>
+ Une troisi�me option est de seulement mapper vers des tables les classes
concr�tes
+ d'une hi�rarchie d'h�ritage, (strat�gie de type
table-per-concrete-class) o�
+ chaque table d�finit tous les �tats persistants de la classe, y compris
les �tats h�rit�s.
+ Dans Hibernate il n'est absolument pas n�cessaire de mapper
explicitement de telles hi�rarchies
+ d'h�ritage. Vous pouvez simplement mapper chaque classe avec une
d�claration <literal><class></literal>
+ diff�rente. Cependant, si vous souhaitez utiliser des associations
polymorphiques (c�d une association
+ vers la superclasse de la hi�rarchie), vous devez utiliser le mapping
<literal><union-subclass></literal>.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="unionsubclass1" coords="2 45"/>
+ <area id="unionsubclass2" coords="3 45"/>
+ <area id="unionsubclass3" coords="4 45"/>
+ <area id="unionsubclass4" coords="5 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<union-subclass
+ name="ClassName"
+ table="tablename"
+ proxy="ProxyInterface"
+ lazy="true|false"
+ dynamic-update="true|false"
+ dynamic-insert="true|false"
+ schema="schema"
+ catalog="catalog"
+ extends="SuperclassName"
+ abstract="true|false"
+ persister="ClassName"
+ subselect="SQL expression"
+ entity-name="EntityName">
+
+ <property .... />
+ .....
+</union-subclass>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="unionsubclass1">
+ <para>
+ <literal>name</literal> : Le nom Java complet de
la sous-classe.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass2">
+ <para>
+ <literal>table</literal> : nom de la table de la
sous-classe.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass3">
+ <para>
+ <literal>proxy</literal> (optionnel) : Indique
une classe ou interface pour le chargement diff�r� des proxies.
+ </para>
+ </callout>
+ <callout arearefs="unionsubclass4">
+ <para>
+ <literal>lazy</literal> (optionnel, par d�faut �
<literal>true</literal>) : Indiquer
+ <literal>lazy="false"</literal>
d�sactive l'utilisation du chargement � la demande.
+ </para>
+
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Aucune colonne discriminante ou colonne clef n'est requise pour cette
strat�gie de mapping.
+ </para>
+ <para>
+ Pour des informations sur les mappings d'h�ritage, voir <xref
linkend="inheritance"/>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-join" revision="3">
+ <title>join</title>
+ <para>
+ En utilisant l'�l�ment
<literal><join></literal>, il est possible de mapper
+ des propri�t�s d'une classe sur plusieurs tables.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="join1" coords="2 50"/>
+ <area id="join2" coords="3 50"/>
+ <area id="join3" coords="4 50"/>
+ <area id="join4" coords="5 50"/>
+ <area id="join5" coords="6 50"/>
+ <area id="join6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<join
+ table="tablename"
+ schema="owner"
+ catalog="catalog"
+ fetch="join|select"
+ inverse="true|false"
+ optionnel="true|false">
+
+ <key ... />
+
+ <property ... />
+ ...
+</join>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="join1">
+ <para>
+ <literal>table</literal> : Le nom de la table
jointe.
+ </para>
+ </callout>
+ <callout arearefs="join2">
+ <para>
+ <literal>schema</literal> (optionnel) :
court-circuite le nom de sch�ma sp�cifi� par l'�l�ment de base
+
<literal><hibernate-mapping></literal>.
+ </para>
+ </callout>
+ <callout arearefs="join3">
+ <para>
+ <literal>catalog</literal> (optionnel) :
court-circuite le nom de catalogue sp�cifi� par l'�l�ment de base
+
<literal><hibernate-mapping></literal>.
+ </para>
+ </callout>
+ <callout arearefs="join4">
+ <para>
+ <literal>fetch</literal> (optionnel - par d�faut
� <literal>join</literal>) :
+ Si positionn� � <literal>join</literal>,
Hibernate utilisera une jointure interne pour charger
+ une <literal>jointure</literal> d�finie par une
classe ou ses super-classes et une jointure externe
+ pour une
<literal><jointure></literal> d�finie par une sous-classe.
+ Si positionn� � <literal>select</literal> alors
Hibernate utilisera un select s�quentiel
+ pour une
<literal><jointure></literal> d�finie sur une sous-classe, qui
ne sera d�livr�e que
+ si une ligne se repr�sente une instance de la sous-classe.
Les jointures internes seront quand m�me
+ utilis�es pour charger une
<literal><jointure></literal> d�finie par une classe et ses
super-classes.
+ </para>
+ </callout>
+ <callout arearefs="join5">
+ <para>
+ <literal>inverse</literal> (optionnel - par
d�faut � <literal>false</literal>) :
+ Si positionn� � true, Hibernate n'essaiera pas
d'ins�rer ou de mettre � jour les
+ propri�t�s d�finies par cette jointure.
+ </para>
+ </callout>
+ <callout arearefs="join6">
+ <para>
+ <literal>optionnel</literal> (optionnel - par
d�faut � <literal>false</literal>) :
+ Si positionn� � true, Hibernate ins�rera une ligne seulement
si les propri�t�s d�finies
+ par cette jointure sont non-nulles et utilisera toujours une
jointure externe pour charger les propri�t�s.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Par exemple, les informations d'adresse pour une personne peuvent
�tre mapp�es vers une table
+ s�par�e (tout en pr�servant des s�mantiques de type valeur pour toutes
ses propri�t�s) :
+ </para>
+ <programlisting><![CDATA[<class name="Person"
+ table="PERSON">
+
+ <id name="id" column="PERSON_ID">...</id>
+
+ <join table="ADDRESS">
+ <key column="ADDRESS_ID"/>
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </join>
+ ...]]></programlisting>
+ <para>
+ Cette fonctionnalit� est souvent seulement utile pour les mod�les de
donn�es
+ h�rit�s d'anciens syst�mes (legacy), nous recommandons d'utiliser
moins de tables que de classes
+ et un mod�le de domaine � granularit� fine. Cependant, c'est utile
+ pour passer d'une strat�gie de mapping d'h�ritage � une autre
dans une hi�rarchie simple ainsi qu'il est
+ expliqu� plus tard.
+ </para>
+ </sect2>
+ <sect2 id="mapping-declaration-key">
+ <title>key</title>
+ <para>
+ Nous avons rencontr� l'�l�ment
<literal><key></literal> � plusieurs reprises maintenant.
+ Il appara�t partout que l'�l�ment de mapping parent d�finit une
jointure sur une nouvele table, et
+ d�finit la clef �trang�re dans la table jointe, ce qui r�f�rence la clef
primaire de la table d'origine.
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="key1" coords="2 50"/>
+ <area id="key2" coords="3 50"/>
+ <area id="key3" coords="4 50"/>
+ <area id="key4" coords="5 50"/>
+ <area id="key5" coords="6 50"/>
+ <area id="key6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<key
+ column="columnname"
+ on-delete="noaction|cascade"
+ property-ref="propertyName"
+ not-null="true|false"
+ update="true|false"
+ unique="true|false"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="key1">
+ <para>
+ <literal>column</literal> (optionnel) : Le nom de
la colonne de la clef �trang�re
+ Cela peut aussi �tre sp�cifi� par l'�l�ment(s) int�gr�(s)
<literal><column></literal>.
+ </para>
+ </callout>
+ <callout arearefs="key2">
+ <para>
+ <literal>on-delete</literal> (optionnel, par
d�faut � <literal>noaction</literal>) :
+ Indique si la contrainte de clef �trang�re poss�de la
possibilit� au niveau base de donn�es
+ de suppression en cascade.
+ </para>
+ </callout>
+ <callout arearefs="key3">
+ <para>
+ <literal>property-ref</literal> (optionnel) :
Indique que la clef �trang�re fait
+ r�f�rence � des colonnes qui ne sont pas la clef primaire de
la table d'origine
+ (Pour les donn�es de syst�mes legacy).
+ </para>
+ </callout>
+ <callout arearefs="key4">
+ <para>
+ <literal>not-null</literal> (optionnel) : Indique
que les colonnes des clefs �trang�res ne
+ peuvent pas �tre nulles (c'est implicite si la clef
�trang�re fait partie de la clef primaire).
+ </para>
+ </callout>
+ <callout arearefs="key5">
+ <para>
+ <literal>update</literal> (optionnel) : Indique
que la clef �trang�re ne devrait jamais �tre mise � jour
+ (implicite si celle-ci fait partie de la clef primaire).
+ </para>
+ </callout>
+ <callout arearefs="key6">
+ <para>
+ <literal>unique</literal> (optionnel) : Indique
que la clef �trang�re doit poss�der une contrainte
+ d'unicit� (implicite si la clef �trang�re est aussi la
clef primaire).
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Nous recommandons pour les syst�mes o� les suppressions doivent �tre
performantes de d�finir toutes
+ les clefs <literal>on-delete="cascade"</literal>,
ainsi Hibernate utilisera une contrainte
+ <literal>ON CASCADE DELETE</literal> au niveau base de
donn�es, plut�t que de nombreux
+ <literal>DELETE</literal> individuels. Attention, cette
fonctionnalit� court-circuite la strat�gie
+ habituelle de verrou optimiste pour les donn�es versionn�es.
+ </para>
+ <para>
+ Les attributs <literal>not-null</literal> et
<literal>update</literal> sont utiles pour
+ mapper une association one-to-many unidirectionnelle. Si vous mappez un
one-to-many unidirectionnel
+ vers une clef �trang�re non nulle, vous
<emphasis>devez</emphasis> d�clarer la colonne de la clef
+ en utilisant <literal><key
not-null="true"></literal>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-column" revision="4">
+ <title>�l�ments column et formula</title>
+ <para>
+ Tout �l�ment de mapping qui accepte un attribut
<literal>column</literal> acceptera alternativement
+ un sous-�l�ment <literal><column></literal>. De
fa�on identique, <literal><formula></literal>
+ est une alternative � l'attribut
<literal>formula</literal>.
+ </para>
+ <programlisting><![CDATA[<column
+ name="column_name"
+ length="N"
+ precision="N"
+ scale="N"
+ not-null="true|false"
+ unique="true|false"
+ unique-key="multicolumn_unique_key_name"
+ index="index_name"
+ sql-type="sql_type_name"
+ check="SQL expression"/>]]></programlisting>
+ <programlisting><![CDATA[<formula>SQL
expression</formula>]]></programlisting>
+ <para>
+ Les attributs <literal>column</literal> et
<literal>formula</literal> peuvent m�me �tre combin�s
+ au sein d'une m�me propri�t� ou mapping d'association pour
exprimer, par exemple, des conditions
+ de jointure exotiques.
+ </para>
+ <programlisting><![CDATA[<many-to-one
name="homeAddress" class="Address"
+ insert="false" update="false">
+ <column name="person_id" not-null="true"
length="10"/>
+ <formula>'MAILING'</formula>
+</many-to-one>]]></programlisting>
+ </sect2>
+ <sect2 id="mapping-declaration-import">
+ <title>import</title>
+ <para>
+ Supposez que votre application poss�de deux classes persistantes du m�me
nom, et vous ne voulez pas pr�ciser
+ le nom Java complet (packages inclus) dans les queries Hibernate. Les
classes peuvent alors �tre "import�es"
+ explicitement plut�t que de compter sur
<literal>auto-import="true"</literal>.Vous pouvez m�me importer
+ des classes et interfaces qui ne sont pas mapp�es explicitement.
+ </para>
+ <programlisting><![CDATA[<import
class="java.lang.Object"
rename="Universe"/>]]></programlisting>
+ <programlistingco>
+ <areaspec>
+ <area id="import1" coords="2 40"/>
+ <area id="import2" coords="3 40"/>
+ </areaspec>
+ <programlisting><![CDATA[<import
+ class="ClassName"
+ rename="ShortName"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="import1">
+ <para>
+ <literal>class</literal> : Nom Java complet de la
classe.
+ </para>
+ </callout>
+ <callout arearefs="import2">
+ <para>
+ <literal>rename</literal> (optionnel - par d�faut
vaut le nom de la classe Java (sans package)) :
+ Nom pouvant �tre utilis� dans le langage de requ�te.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ </sect2>
+ <sect2 id="mapping-types-anymapping" revision="2">
+ <title>any</title>
+ <para>
+ Il existe encore un type de mapping de propri�t�. L'�l�ment de
mapping <literal><any></literal>
+ d�finit une association polymorphique vers des classes de tables
multiples. Ce type de mapping requiert
+ toujours plus d'une colonne. La premi�re colonne contient le type de
l'entit� associ�e. Les colonnes
+ restantes contiennent l'identifiant. il est impossible de sp�cifier
une contrainte de clef �trang�re
+ pour ce type d'association, donc ce n'est certainement pas
consid�r� comme le moyen habituel de mapper
+ des associations (polymorphiques). Vous devriez utiliser cela uniquement
dans des cas particuliers
+ (par exemple des logs d'audit, des donn�es de session utilisateur,
etc...).
+ </para>
+ <para>
+ L'attribut <literal>meta-type</literal> permet �
l'application de sp�cifier un type personnalis� qui mappe
+ des valeurs de colonnes de le base de donn�es sur des classes
persistantes qui ont un attribut identifiant
+ du type sp�cifi� par <literal>id-type</literal>. Vous devez
sp�cifier le mapping � partir de valeurs du
+ m�ta-type sur les noms des classes.
+ </para>
+ <programlisting><![CDATA[<any name="being"
id-type="long" meta-type="string">
+ <meta-value value="TBL_ANIMAL" class="Animal"/>
+ <meta-value value="TBL_HUMAN" class="Human"/>
+ <meta-value value="TBL_ALIEN" class="Alien"/>
+ <column name="table_name"/>
+ <column name="id"/>
+</any>]]></programlisting>
+ <programlistingco>
+ <areaspec>
+ <area id="any1" coords="2 50"/>
+ <area id="any2" coords="3 50"/>
+ <area id="any3" coords="4 50"/>
+ <area id="any4" coords="5 50"/>
+ <area id="any5" coords="6 50"/>
+ <area id="any6" coords="7 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<any
+ name="propertyName"
+ id-type="idtypename"
+ meta-type="metatypename"
+ cascade="cascade_style"
+ access="field|property|ClassName"
+ optimistic-lock="true|false"
+>
+ <meta-value ... />
+ <meta-value ... />
+ .....
+ <column .... />
+ <column .... />
+ .....
+</any>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="any1">
+ <para>
+ <literal>name</literal> : le nom de la
propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="any2">
+ <para>
+ <literal>id-type</literal> : le type
identifiant.
+ </para>
+ </callout>
+ <callout arearefs="any3">
+ <para>
+ <literal>meta-type</literal> (optionnel - par
d�faut � <literal>string</literal>) :
+ Tout type permis pour un mapping par discriminateur.
+ </para>
+ </callout>
+ <callout arearefs="any4">
+ <para>
+ <literal>cascade</literal> (optionnel - par
d�faut � <literal>none</literal>) :
+ le style de cascade.
+ </para>
+ </callout>
+ <callout arearefs="any5">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut
� <literal>property</literal>) : La strat�gie
+ � utiliser par Hibernate pour acc�der � cette propri�t�.
+ </para>
+ </callout>
+ <callout arearefs="any6">
+ <para>
+ <literal>optimistic-lock</literal> (optionnel -
par d�faut � <literal>true</literal>) :
+ Indique que les mises � jour sur cette propri�t� n�cessitent
ou non l'acquisition d'un
+ verrou optimiste. En d'autres termes, d�finit si un
incr�ment de version doit avoir lieu
+ quand cette propri�t� est marqu�e dirty.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ </sect2>
+ </sect1>
+ <sect1 id="mapping-types">
+ <title>Hibernate Types</title>
+ <sect2 id="mapping-types-entitiesvalues" revision="1">
+ <title>Entit�s et valeurs</title>
+ <para>
+ Pour comprendre le comportement des diff�rents objets Java par rapport au
service
+ de persistance, nous avons besoin de les classer en deux groupes :
+ </para>
+ <para>
+ Une <emphasis>entit�</emphasis> existe ind�pendamment de tout
autre objet poss�dant
+ une r�f�rence vers l'entit�. Comparez cela avec le mod�le Java
habituel o� un objet
+ est supprim� par le garbage collector d�s qu'il n'est plus
r�f�renc�. Les entit�s
+ doivent �tre explicitement enregistr�es et supprim�es (sauf dans les cas
o�
+ sauvegardes et suppressions sont
<emphasis>cascad�es</emphasis> d'une entit� m�re
+ vers ses enfants). C'est diff�rent du mod�le ODMG de persistance par
+ atteignabilit� - et correspond mieux � la fa�on dont les objets sont
+ habituellement utilis�s dans des grands syst�mes. Les entit�s permettent
les r�f�rences
+ circulaires et partag�es. Elles peuvent aussi �tre versionn�es.
+ </para>
+ <para>
+ L'�tat persistant d'une entit� consiste en des r�f�rences vers
d'autres entit�s et
+ instances de types <emphasis>valeurs</emphasis>. Ces valeurs
sont des types primitifs,
+ des collections (et non le contenu d'une collection), des composants
de certains objets
+ immuables. Contrairement aux entit�s, les valeurs (et en particulier les
collections et
+ composants) <emphasis>sont</emphasis> persist�s par
atteignabiliit�. Comme les
+ valeurs (et types primitifs) sont persist�s et supprim�s avec
l'entit� qui les contient,
+ ils ne peuvent pas poss�der leurs propres versions. Les valeurs n'ont
pas d'identit�
+ ind�pendantes, ainsi elles ne peuvent pas �tre partag�es par deux entit�s
ou collections.
+ </para>
+ <para>
+ Jusqu'� pr�sent nous avons utilis� le terme "classe
persistante" pour parler d'entit�s.
+ Nous allons continuer � faire ainsi. Cependant, au sens strict, toutes
+ les classes d�finies par un utilisateur poss�dant un �tat persistant ne
sont pas des
+ entit�s. Un <emphasis>composant</emphasis> est une classe
d�finie par un utilisateur
+ avec les caract�ristiques d'une valeur. Une propri�t� Java de type
<literal>java.lang.String</literal>
+ a aussi les caract�ristiques d'une valeur.
+
+ <!-- FIXME Baptiste MATHUS : J'ai remis le texte anglais pour que
si la version est publi�e
+ comme �a, au moins le lecteur puisse essayer lui aussi de comprendre la
version anglaise... -->
+
+ Given this definition, we can say that all types (classes) provided
+ by the JDK have value type semantics in Java, while user-defined types
may
+ be mapped with entity or value type semantics. This decision is up to
the
+ application developer. A good hint for an entity class in a domain model
are
+ shared references to a single instance of that class, while composition
or
+ aggregation usually translates to a value type.
+ </para>
+ <para>
+ Nous nous pencherons sur ces deux concepts tout au long de la
documentation.
+ </para>
+ <para>
+ Le d�fi est de mapper les type Javas (et la d�finition des d�veloppeurs
des
+ entit�s et valeurs types) sur les types du SQL ou des bases de donn�es.
Le pont
+ entre les deux syst�mes est propos� par Hibernate : pour les entit�s nous
utilisons
+ <literal><class></literal>,
<literal><subclass></literal> et ainsi de suite.
+ Pour les types valeurs nous utilisons
<literal><property></literal>,
+ <literal><component></literal>, etc.,
habituellement avec un attribut <literal>type</literal>.
+ La valeur de cet attribut est le nom d'un <emphasis>type de
mapping</emphasis> Hibernate.
+ Hibernate propose de base de nombreux mappings (pour les types de valeurs
standards du JDK).
+ Vous pouvez �crire vos propres types de mappings et impl�menter aussi vos
propres strat�gies
+ de conversion, nous le verrons plus tard.
+ </para>
+ <para>
+ Tous les types propos�s de base par Hibernate � part les collections
autorisent la valeur null.
+ </para>
+ </sect2>
+ <sect2 id="mapping-types-basictypes" revision="3">
+ <title>Basic value types</title>
+ <para>
+ Les <emphasis>types basiques de mapping</emphasis> propos�s
de base peuvent grossi�rement �tre
+ rang�s dans les cat�gories suivantes :
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal>integer, long, short, float, double,
character, byte,
+ boolean, yes_no, true_false</literal>
+ </term>
+ <listitem>
+ <para>
+ Les mappings de type des primitives Java ou leurs classes
wrappers (ex: Integer
+ pour int) vers les types SQL (propri�taires) appropri�s.
<literal>boolean,
+ yes_no</literal>et
<literal>true_false</literal> sont tous des alternatives
+ pour les types Java
<literal>boolean</literal> ou
<literal>java.lang.Boolean</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>string</literal>
+ </term>
+ <listitem>
+ <para>
+ Mapping de type de
<literal>java.lang.String</literal> vers
+ <literal>VARCHAR</literal> (ou le
<literal>VARCHAR2</literal> Oracle).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>date, time, timestamp</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappings de type pour
<literal>java.util.Date</literal> et ses sous-classes
+ vers les types SQL <literal>DATE</literal>,
<literal>TIME</literal> et
+ <literal>TIMESTAMP</literal> (ou
�quivalent).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>calendar, calendar_date</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappings de type pour
<literal>java.util.Calendar</literal> vers les types SQL
+ <literal>TIMESTAMP</literal> et
<literal>DATE</literal>
+ (ou �quivalent).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>big_decimal, big_integer</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappings de type pour
<literal>java.math.BigDecimal</literal> et
+ <literal>java.math.BigInteger</literal> vers
<literal>NUMERIC</literal>
+ (ou le <literal>NUMBER</literal> Oracle).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>locale, timezone, currency</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappings de type pour
<literal>java.util.Locale</literal>,
+ <literal>java.util.TimeZone</literal> et
+ <literal>java.util.Currency</literal>
+ vers <literal>VARCHAR</literal> (ou le
<literal>VARCHAR2</literal> Oracle).
+ Les instances de <literal>Locale</literal> et
<literal>Currency</literal> sont
+ mapp�es sur leurs codes ISO. Les instances de
<literal>TimeZone</literal> sont
+ mapp�es sur leur <literal>ID</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>class</literal>
+ </term>
+ <listitem>
+ <para>
+ Un type de mapping pour
<literal>java.lang.Class</literal> vers
+ <literal>VARCHAR</literal> (ou le
<literal>VARCHAR2</literal> Oracle).
+ Un objet <literal>Class</literal> est mapp�
sur son nom Java complet.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>binary</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappe les tableaux de bytes vers le type binaire SQL
appropri�.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>text</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappe les longues cha�nes de caract�res Java vers les
types SQL
+ <literal>CLOB</literal> ou
<literal>TEXT</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>serializable</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappe les types Java s�rialisables vers le type SQL
binaire appropri�. Vous pouvez
+ aussi indiquer le type Hibernate
<literal>serializable</literal> avec le nom
+ d'une classe Java s�rialisable ou une interface qui
ne soit pas par d�faut un type de base.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>clob, blob</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappings de type pour les classes JDBC
<literal>java.sql.Clob</literal> and
+ <literal>java.sql.Blob</literal>. Ces types
peuvent ne pas convenir pour certaines
+ applications car un objet blob ou clob peut ne pas �tre
r�utilisable en dehors
+ d'une transaction (de plus l'impl�mentation par
les pilotes est moyennement bonne).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <literal>imm_date, imm_time, imm_timestamp,
imm_calendar, imm_calendar_date,
+ imm_serializable, imm_binary</literal>
+ </term>
+ <listitem>
+ <para>
+ Mappings de type pour ceux qui sont habituellement
modifiable, pour lesquels
+ Hibernate effectue certains optimisations convenant
seulement aux types Java immuables,
+ et l'application les traite comme immuable.
+ Par exemple, vous ne devriez pas appeler
<literal>Date.setTime()</literal> sur une instance
+ mapp�e sur un
<literal>imm_timestamp</literal>. Pour changer la valeur
+ de la propri�t�, et faire que cette modification soit
persist�e, l'application
+ doit assigner un nouvel (non identique) objet � la
propri�t�.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ Les identifiants uniques des entit�s et collections peuvent �tre de
n'importe quel type de base except�
+ <literal>binary</literal>,
<literal>blob</literal> et <literal>clob</literal> (les
identifiants
+ composites sont aussi permis, voir plus bas).
+ </para>
+ <para>
+ Les types de base des valeurs ont des <literal>Type</literal>
constants correspondants d�finis
+ dans <literal>org.hibernate.Hibernate</literal>. Par exemple,
<literal>Hibernate.STRING</literal>
+ repr�sent� le type <literal>string</literal>.
+ </para>
+ </sect2>
+ <sect2 id="mapping-types-custom" revision="2">
+ <title>Types de valeur d�finis par l'utilisateur</title>
+ <para>
+ Il est assez facile pour les d�veloppeurs de cr�er leurs propres types de
valeurs. Par exemple,
+ vous pourriez vouloir persister des propri�t�s du type
<literal>java.lang.BigInteger</literal>
+ dans des colonnnes <literal>VARCHAR</literal>. Hibernate ne
procure pas par d�faut un type pour cela.
+ Mais les types que vous pouvez cr�er ne se limitent pas � mapper des
propri�t�s (ou �l�ment collection)
+ � une simple colonne d'une table. Donc, par exemple, vous pourriez
avoir une propri�t� Java
+
<literal>getName()</literal>/<literal>setName()</literal> de type
+ <literal>java.lang.String</literal> persist�e dans les
colonnes
+ <literal>FIRST_NAME</literal>,
<literal>INITIAL</literal>, <literal>SURNAME</literal>.
+ </para>
+ <para>
+ Pour impl�menter votre propre type, vous pouvez soit impl�menter
<literal>org.hibernate.UserType</literal>
+ soit <literal>org.hibernate.CompositeUserType</literal> et
d�clarer des propri�t�s utilisant des
+ noms de classes complets du type. Regardez
<literal>org.hibernate.test.DoubleStringType</literal>
+ pour voir ce qu'il est possible de faire.
+ </para>
+ <programlisting><![CDATA[<property name="twoStrings"
type="org.hibernate.test.DoubleStringType">
+ <column name="first_string"/>
+ <column name="second_string"/>
+</property>]]></programlisting>
+ <para>
+ Remarquez l'utilisation des tags
<literal><column></literal> pour mapper une propri�t� sur des
colonnes
+ multiples.
+ </para>
+ <para>
+ Les interfaces <literal>CompositeUserType</literal>,
<literal>EnhancedUserType</literal>,
+ <literal>UserCollectionType</literal>, et
<literal>UserVersionType</literal> permettent des utilisations
+ plus sp�cialis�es.
+ </para>
+ <para>
+ Vous pouvez m�me donner des param�tres en indiquant
<literal>UserType</literal> dans le fichier
+ de mapping ; Pour cela, votre <literal>UserType</literal>
doit impl�menter l'interface
+ <literal>org.hibernate.usertype.ParameterizedType</literal>.
Pour sp�cifier des param�tres dans
+ votre type propre, vous pouvez utiliser l'�l�ment
<literal><type></literal> dans vos fichiers de mapping.
+ </para>
+ <programlisting><![CDATA[<property name="priority">
+ <type name="com.mycompany.usertypes.DefaultValueIntegerType">
+ <param name="default">0</param>
+ </type>
+</property>]]></programlisting>
+ <para>
+ Le <literal>UserType</literal> permet maintenant de r�cup�rer
la valeur pour le param�tre nomm�
+ <literal>default</literal> � partir de l'objet
<literal>Properties</literal> qui lui est pass�.
+ </para>
+ <para>
+ Si vous utilisez fr�quemment un <literal>UserType</literal>,
cela peut �tre utile de lui d�finir un
+ nom plus court. Vous pouvez faire cela en utilisant l'�l�ment
<literal><typedef></literal>.
+ Les typedefs permettent d'assigner un nom � votre type propre et
peuvent aussi contenir une liste de
+ valeurs de param�tres par d�faut si ce type est param�tr�.
+ </para>
+ <programlisting><![CDATA[<typedef
class="com.mycompany.usertypes.DefaultValueIntegerType"
name="default_zero">
+ <param name="default">0</param>
+</typedef>]]></programlisting>
+ <programlisting><![CDATA[<property name="priority"
type="default_zero"/>]]></programlisting>
+ <para>
+ Il est aussi possible de red�finir les param�tres par d�faut du typedef
au cas par cas en
+ utilisant des param�tres type sur le mapping de la propri�t�.
+ </para>
+ <para>
+ Bien que le fait que Hibernate propose de base une riche vari�t� de
types, et qu'il supporte les composants
+ signifie que vous aurez tr�s rarement
<emphasis>besoin</emphasis> d'utiliser un nouveau type propre,
+ il est n�anmoins de bonne pratique d'utiliser des types propres pour
les classes (non entit�s) qui
+ apparaissent fr�quemment dans votre application. Par exemple une classe
<literal>MonetaryAmount</literal>
+ est un bon candidat pour un
<literal>CompositeUserType</literal> m�me s'il pourrait facilement
+ �tre mapp� comme un composant. Une motivation pour cela est
l'abstraction. Avec un type propre
+ vos documents de mapping sont � l'abri des changements futurs dans
votre fa�on de repr�senter des
+ valeurs mon�taires.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mapping-entityname">
+ <title>Mapper une classe plus d'une fois</title>
+ <para>
+ Il est possible de proposer plus d'un mapping par classe persistante.
Dans ce cas, vous
+ devez sp�cifier un <emphasis>nom d'entit�</emphasis> pour
lever l'ambiguit� entre les instances
+ des entit�s mapp�es (par d�faut, le nom de l'entit� est celui de la
classe). Hibernate
+ vous permet de sp�cifier le nom de l'entit� lorsque vous utilisez des
objets persistants, lorsque
+ vous �crivez des requ�tes ou quand vous mappez des associations vers les
entit�s nomm�es.
+ </para>
+
+ <programlisting><![CDATA[<class name="Contract"
table="Contracts"
+ entity-name="CurrentContract">
+ ...
+ <set name="history" inverse="true"
+ order-by="effectiveEndDate desc">
+ <key column="currentContractId"/>
+ <one-to-many entity-name="HistoricalContract"/>
+ </set>
+</class>
+
+<class name="Contract" table="ContractHistory"
+ entity-name="HistoricalContract">
+ ...
+ <many-to-one name="currentContract"
+ column="currentContractId"
+ entity-name="CurrentContract"/>
+</class>]]></programlisting>
+
+ <para>
+ Remarquez comment les associations sont d�sormais sp�cifi�es en utilisant
+ <literal>entity-name</literal> au lieu de
<literal>class</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="mapping-quotedidentifiers">
+ <title>SQL quoted identifiers</title>
+ <para>
+ Vous pouvez forcer Hibernate � mettre un identifiant entre quotes dans le SQL
g�n�r� en mettant le nom
+ de la table ou de la colonne entre backticks dans le
+ document de mapping. Hibernate utilisera les bons styles de quotes pour le
<literal>Dialect</literal> SQL
+ (habituellement des doubles quotes, mais des parenth�ses pour SQL server et
des backticks pour MySQL).
+ </para>
+ <programlisting><![CDATA[<class name="LineItem"
table="`Line Item`">
+ <id name="id" column="`Item Id`"/><generator
class="assigned"/></id>
+ <property name="itemNumber" column="`Item #`"/>
+ ...
+</class>]]></programlisting>
+ </sect1>
+ <sect1 id="mapping-alternatives">
+ <title>alternatives Metadata</title>
+ <para>
+ XML ne convient pas � tout le monde, il y a donc des moyens alternatifs pour
d�finir des metatda
+ de mappings O/R dans Hibernate.
+ </para>
+ <sect2 id="mapping-xdoclet">
+ <title>utilisation de XDoclet</title>
+ <para>
+ De nombreux utilisateurs de Hibernate pr�f�rent embarquer les
informations de mappings
+ directement au sein du code source en utilisant les tags XDoclet
<literal>(a)hibernate.tags</literal>.
+ Nous ne couvrons pas cette approche dans ce document cependant, puisque
c'est consid�r� comme faisant partie
+ de XDoclet. Cependant, nous pr�sentons l'exemple suivant de la classe
<literal>Cat</literal> avec
+ des mappings XDoclet.
+ </para>
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+/**
+ * @hibernate.class
+ * table="CATS"
+ */
+public class Cat {
+ private Long id; // identifier
+ private Date birthdate;
+ private Cat mother;
+ private Set kittens
+ private Color color;
+ private char sex;
+ private float weight;
+
+ /*
+ * @hibernate.id
+ * generator-class="native"
+ * column="CAT_ID"
+ */
+ public Long getId() {
+ return id;
+ }
+ private void setId(Long id) {
+ this.id=id;
+ }
+
+ /**
+ * @hibernate.many-to-one
+ * column="PARENT_ID"
+ */
+ public Cat getMother() {
+ return mother;
+ }
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+
+ /**
+ * @hibernate.property
+ * column="BIRTH_DATE"
+ */
+ public Date getBirthdate() {
+ return birthdate;
+ }
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ /**
+ * @hibernate.property
+ * column="WEIGHT"
+ */
+ public float getWeight() {
+ return weight;
+ }
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+
+ /**
+ * @hibernate.property
+ * column="COLOR"
+ * not-null="true"
+ */
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+ /**
+ * @hibernate.set
+ * inverse="true"
+ * order-by="BIRTH_DATE"
+ * @hibernate.collection-key
+ * column="PARENT_ID"
+ * @hibernate.collection-one-to-many
+ */
+ public Set getKittens() {
+ return kittens;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kittens.add(kitten);
+ }
+
+ /**
+ * @hibernate.property
+ * column="SEX"
+ * not-null="true"
+ * update="false"
+ */
+ public char getSex() {
+ return sex;
+ }
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+}]]></programlisting>
+ <para>
+ Voyez le site web de Hibernate pour plus d'exemples sur XDoclet et
Hibernate.
+ </para>
+ </sect2>
+ <sect2 id="mapping-annotations" revision="2">
+ <title>Utilisation des annotations JDK 5.0</title>
+ <para>
+ Le JDK 5.0 introduit des annotations proches de celles de XDoclet au
niveau java, qui sont
+ type-safe et v�rifi�es � la compilation. Ce m�canisme est plus puissant
que XDoclet et mieux
+ support� par les outils et IDE. IntelliJ IDEA, par exemple, supporte
l'auto-compl�tion et le
+ surlignement syntaxique des annotations JDK 5.0. La nouvelle r�vision des
sp�cifications des EJB
+ (JSR-220) utilise les annotations JDK 5.0 comme m�canisme primaire pour
les meta-donn�es des beans entit�s.
+ Hibernate3 impl�mente l'<literal>EntityManager</literal>
de la JSR-220 (API de persistance),
+ le support du mapping de meta-donn�es est disponible via le package
<emphasis>Hibernate Annotations</emphasis>,
+ en tant que module s�par� � t�l�charger. EJB3 (JSR-220) et les m�tadata
Hibernate3 sont support�s.
+ </para>
+ <para>
+ Ceci est un exemple d'une classe POJO annot�e comme un EJB entit� :
+ </para>
+ <programlisting><![CDATA[@Entity(access = AccessType.FIELD)
+public class Customer implements Serializable {
+
+ @Id;
+ Long id;
+
+ String firstName;
+ String lastName;
+ Date birthday;
+
+ @Transient
+ Integer age;
+
+ @Embedded
+ private Address homeAddress;
+
+ @OneToMany(cascade=CascadeType.ALL)
+ @JoinColumn(name="CUSTOMER_ID")
+ Set<Order> orders;
+
+ // Getter/setter and business methods
+}]]></programlisting>
+ <para>
+ Notez que le support des annotations JDK 5.0 (et de la JSR-220) est
encore en cours et n'est pas termin�.
+ R�f�rez vous au module Hibernate Annotation pour plus de d�tails.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mapping-generated" revision="1">
+ <title>Propri�t�s g�n�r�es</title>
+ <para>
+ Les propri�t�s g�n�r�es sont des propri�t�s dont les valeurs sont g�n�r�es
par
+ la base de donn�es. Typiquement, les applications Hibernate avaient besoin
d'invoquer
+ <literal>refresh</literal> sur les instances qui contenaient des
propri�t�s pour lesquelles
+ la base de donn�es g�n�rait des valeurs. Marquer les propri�t�s comme
g�n�r�es permet �
+ l'application de d�l�guer cette responsabilit� � Hibernate.
Principalement, � chaque fois
+ qu'Hibernate r�alise une insertion ou une mise � jour en base de donn�es
pour une entit�
+ marqu�e comme telle, cela provoque imm�diatement un select pour r�cup�rer les
valeurs g�n�r�es.
+ </para>
+ <para>
+ Les propri�t�s marqu�es comme g�n�r�es doivent de plus ne pas �tre ins�rables
et modifiables
+ Seuls <xref
linkend="mapping-declaration-version">versions</xref>,
+ <xref
linkend="mapping-declaration-timestamp">timestamps</xref>, et
+ <xref linkend="mapping-declaration-property">simple
properties</xref> peuvent �tre marqu�s comme
+ g�n�r�es.
+ </para>
+ <para>
+ <literal>never</literal> (par d�faut) - indique la valeur de la
propri�t� n'est pas g�n�r�e
+ dans la base de donn�es.
+ </para>
+ <para>
+ <literal>insert</literal> - indique que la valeur de la propri�t�
donn�e est
+ g�n�r�e � l'insertion mais pas lors des futures mises � jour de
l'enregistrement.
+ Les colonnes de type "date de cr�ation" sont le cas
d'utilisation typique de cette option.
+ Notez que m�me les propri�t�s <xref
linkend="mapping-declaration-version">version</xref> et
+ <xref
linkend="mapping-declaration-timestamp">timestamp</xref> peuvent �tre
+ d�clar�es comme g�n�r�es, cette option n'est pas disponible � cet
endroit...
+ </para>
+ <para>
+ <literal>always</literal> - indique que la valeur de la propri�t�
est g�n�r�e � l'insert
+ comme aux updates.
+ </para>
+
+ </sect1>
+
+ <sect1 id="mapping-database-object">
+ <title>Objets auxiliaires de la base de donn�es</title>
+ <para>
+ Permettent les ordres CREATE et DROP d'objets arbitraire de la base de
donn��es, en conjonction avec
+ les outils Hibernate d'�volutions de sch�ma, pour permettre de d�finir
compl�tement
+ un sch�ma utilisateur au sein des fichiers de mapping Hibernate. Bien que
con�u sp�cifiquement
+ pour cr�er et supprimer des objets tels que des triggers et des proc�dures
stock�es,
+ ou toute commande pouvant �tre ex�cut�e via une m�thode de
<literal>java.sql.Statement.execute()</literal>
+ (ALTERs, INSERTS, etc). Il y a principalement deux modes pour d�finir les
objets auxiliaires de base de donn�es...
+ </para>
+ <para>
+ Le premier mode est de lister explicitement les commandes CREATE et DROP dans
le fichier
+ de mapping:
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <create>CREATE TRIGGER my_trigger ...</create>
+ <drop>DROP TRIGGER my_trigger</drop>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ Le second mode est de fournir une classe particuli�re qui connait comment
construire
+ les commandes CREATE et DROP. Cette classe particuli�re doit impl�menter
l'interface
+
<literal>org.hibernate.mapping.AuxiliaryDatabaseObject</literal>.
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ <para>
+ Additionnellement, ces objets de base de donn�es peuvent �tre optionnellement
trait�s
+ selon l'utilisation de dialectes particuliers..
+ </para>
+ <programlisting><![CDATA[<hibernate-mapping>
+ ...
+ <database-object>
+ <definition class="MyTriggerDefinition"/>
+ <dialect-scope name="org.hibernate.dialect.Oracle9Dialect"/>
+ <dialect-scope name="org.hibernate.dialect.OracleDialect"/>
+ </database-object>
+</hibernate-mapping>]]></programlisting>
+ </sect1>
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/batch.xml (from rev
14070, core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/batch.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/batch.xml
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/content/batch.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,329 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="batch">
+ <title>Traitement par paquet</title>
+
+ <para>
+ Une approche na�ve pour ins�rer 100 000 lignes dans la base de donn�es en
utilisant
+ Hibernate pourrait ressembler � �a :
+ </para>
+
+ <programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+}
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Ceci devrait s'�crouler avec une
<literal>OutOfMemoryException</literal> quelque
+ part aux alentours de la 50 000�me ligne. C'est parce qu'Hibernate cache
toutes
+ les instances de <literal>Customer</literal> nouvellement ins�r�es
dans le cache
+ de second niveau.
+ </para>
+
+ <para>
+ Dans ce chapitre nous montrerons comment �viter ce probl�me. D'abord,
cependant,
+ si vous faites des traitements par batch, il est absolument critique que vous
+ activiez l'utilisation ds paquet JDBC (NdT : JDBC batching), si vous avez
l'intention
+ d'obtenir des performances raisonnables. Configurez la taille du paquet JDBC
avec un
+ nombre raisonnable (disons, 10-50) :
+ </para>
+
+ <programlisting><![CDATA[hibernate.jdbc.batch_size
20]]></programlisting>
+
+ <para>
+ Vous pourriez aussi vouloir faire cette sorte de travail dans un traitement o�
+ l'interaction avec le cache de second niveau est compl�tement d�sactiv� :
+ </para>
+
+ <programlisting><![CDATA[hibernate.cache.use_second_level_cache
false]]></programlisting>
+
+ <sect1 id="batch-inserts">
+ <title>Insertions en paquet</title>
+
+ <para>
+ Lorsque vous rendez des nouveaux objets persistants, vous devez r�guli�rement
appeler
+ <literal>flush()</literal> et puis
<literal>clear()</literal> sur la session,
+ pour contr�ler la taille du cache de premier niveau.
+ </para>
+
+ <programlisting><![CDATA[Session session =
sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+for ( int i=0; i<100000; i++ ) {
+ Customer customer = new Customer(.....);
+ session.save(customer);
+ if ( i % 20 == 0 ) { //20, m�me taille que la taille du paquet JDBC
+ //flush un paquet d'insertions et lib�re la m�moire :
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-update" >
+ <title>Paquet de mises � jour</title>
+
+ <para>
+ Pour r�cup�rer et mettre � jour des donn�es les m�mes id�es s'appliquent.
En plus,
+ vous avez besoin d'utiliser <literal>scroll()</literal> pour
tirer partie des
+ curseurs c�t� serveur pour les requ�tes qui retournent beaucoup de lignes de
donn�es.
+ </para>
+
+ <programlisting><![CDATA[Session session =
sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .setCacheMode(CacheMode.IGNORE)
+ .scroll(ScrollMode.FORWARD_ONLY);
+int count=0;
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ if ( ++count % 20 == 0 ) {
+ //flush un paquet de mises � jour et lib�re la m�moire :
+ session.flush();
+ session.clear();
+ }
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="batch-statelesssession">
+ <title>L'interface StatelessSession</title>
+ <para>
+ Alternativement, Hibernate fournit une API orient�e commande qui peut �tre
+ utilis�e avec des flux de donn�es pour et en provenance de la base de
donn�es
+ sous la forme d'objets d�tach�s. Une
<literal>StatelessSession</literal> n'a pas
+ de contexte de persistance associ� et ne fournit pas beaucoup de s�mantique
de
+ dur�e de vie de haut niveau. En particulier, une session sans �tat
n'impl�mente
+ pas de cache de premier niveau et n'interagit pas non plus avec un cache
de
+ seconde niveau ou un cache de requ�tes. Elle n'impl�mente pas les
transactions
+ ou la v�rification sale automatique (NdT : automatic dirty checking). Les
+ op�rations r�alis�es avec une session sans �tat ne sont jamais r�percut�es
+ en cascade sur les instances associ�es. Les collections sont ignor�es par
une
+ session sans �tat. Les op�rations ex�cut�es via une session sans �tat
outrepasse
+ le mod�le d'�v�nements d'Hibernate et les intercepteurs. Les sessions
sans �tat sont
+ vuln�rables aux effets de modification des donn�es, ceci est d� au manque de
cache
+ de premier niveau. Une session sans �tat est une abstraction bas niveau,
plus
+ proche de la couche JDBC sous-jacente.
+ </para>
+
+ <programlisting><![CDATA[StatelessSession session =
sessionFactory.openStatelessSession();
+Transaction tx = session.beginTransaction();
+
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+ .scroll(ScrollMode.FORWARD_ONLY);
+while ( customers.next() ) {
+ Customer customer = (Customer) customers.get(0);
+ customer.updateStuff(...);
+ session.update(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Notez que dans le code de l'exemple, les intances de
<literal>Customer</literal>
+ retourn�es par la requ�te sont imm�diatement d�tach�es. Elles ne sont jamais
+ associ�es � un contexte de persistance.
+ </para>
+
+ <para>
+ Les op�rations <literal>insert()</literal>,
<literal>update()</literal> et
+ <literal>delete()</literal> d�finies par l'interface
<literal>StatelessSession</literal>
+ sont consid�r�es comme des op�rations d'acc�s direct aux lignes de la
base de donn�es,
+ ce qui r�sulte en une ex�cution imm�diate du SQL
<literal>INSERT</literal>, <literal>UPDATE</literal>
+ ou <literal>DELETE</literal> respectif. De l�, elles ont des
s�mantiques tres diff�rentes des
+ op�rations <literal>save()</literal>,
<literal>saveOrUpdate()</literal>
+ et <literal>delete()</literal> d�finies par l'interface
<literal>Session</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="batch-direct" revision="2">
+ <title>Op�rations de style DML</title>
+
+ <para>
+ Comme d�j� discut� avant, le mapping objet/relationnel automatique et
transparent
+ est int�ress� par la gestion de l'�tat de l'objet. Ceci implique que
l'�tat de l'objet
+ est disponible en m�moire, d'o� manipuler (en utilisant des expressions
du langage de
+ manipulation de donn�es - <literal>Data Manipulation
Language</literal> (DML) - SQL)
+ les donn�es directement dans la base n'affectera pas l'�tat en
m�moire. Pourtant, Hibernate
+ fournit des m�thodes pour l'ex�cution d'expression DML de style SQL
lesquelles sont
+ r�alis�es � travers le langage de requ�te d'Hibernate (<xref
linkend="queryhql">HQL</xref>).
+ </para>
+
+ <para>
+ La pseudo-syntaxe pour les expressions <literal>UPDATE</literal>
et <literal>DELETE</literal>
+ est : <literal>( UPDATE | DELETE ) FROM? EntityName (WHERE
where_conditions)?</literal>.
+ Certains points sont � noter :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Dans la clause from, le mot-clef FROM est optionnel
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Il ne peut y avoir qu'une seule entit� nomm�e dans la clause from
; elle peut
+ optionnellement avoir un alias. Si le nom de l'entit� a un alias,
alors
+ n'importe quelle r�f�rence de propri�t� doit �tre qualifi�e en
ayant un alias ;
+ si le nom de l'entit� n'a pas d'alias, alors il est
ill�gal pour n'importe quelle
+ r�f�rence de propri�t� d'�tre qualifi�e.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Aucune jointure (implicite ou explicite) ne peut �tre sp�cifi�e dans
une requ�te HQL.
+ Les sous-requ�tes peuvent �tre utilis�es dans la clause where ; les
sous-requ�tes,
+ elles-m�mes, peuvent contenir des jointures.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ La clause where est aussi optionnelle.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Par exemple, pour ex�cuter un <literal>UPDATE</literal> HQL,
utilisez la m�thode
+ <literal>Query.executeUpdate()</literal> (la m�thode est donn�es
pour ceux
+ qui sont familiers avec
<literal>PreparedStatement.executeUpdate()</literal> de
+ JDBC) :
+ </para>
+
+ <programlisting><![CDATA[Session session =
sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlUpdate = "update Customer c set c.name = :newName where c.name =
:oldName";
+// ou String hqlUpdate = "update Customer set name = :newName where name =
:oldName";
+int updatedEntities = s.createQuery( hqlUpdate )
+ .setString( "newName", newName )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Pour ex�cuter un <literal>DELETE</literal> HQL, utilisez la m�me
m�thode
+ <literal>Query.executeUpdate()</literal> :
+ </para>
+
+ <programlisting><![CDATA[Session session =
sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlDelete = "delete Customer c where c.name = :oldName";
+// or String hqlDelete = "delete Customer where name = :oldName";
+int deletedEntities = s.createQuery( hqlDelete )
+ .setString( "oldName", oldName )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ La valeur du <literal>int</literal> retourn� par la m�thode
<literal>Query.executeUpdate()</literal>
+ indique le nombre d'entit�s affect�es par l'op�ration. Consid�rez que
cela peut ou pas
+ corr�ler le nombre de lignes affect�s dans la base de donn�es. Une op�ration
HQL
+ pourrait entra�ner l'ex�cution de multiples expressions SQL r�elles, pour
des classes
+ filles mapp�es par jointure (NdT: join-subclass), par exemple. Le nombre
retourn�
+ indique le nombre d'entit�s r�elles affect�es par l'expression.
Retour � l'exemple de la
+ classe fille mapp�e par jointure, un effacement d'une des classes filles
peut r�ellement
+ entra�ner des suppressions pas seulement dans la table qui mappe la classe
fille, mais
+ aussi dans la table "racine" et potentillement dans les tables des
classes filles plus bas
+ dans la hi�rarchie d'h�ritage.
+ </para>
+
+ <para>
+ La pseudo-syntaxe pour l'expression <literal>INSERT</literal>
est :
+ <literal>INSERT INTO EntityName properties_list
select_statement</literal>. Quelques
+ points sont � noter :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Seule la forme INSERT INTO ... SELECT ... est support�e ; pas la
forme INSERT INTO ... VALUES ... .
+ </para>
+ <para>
+ La properties_list est analogue � la <literal>sp�cification de
la colonne</literal>
+
+ The properties_list is analogous to the <literal>column
speficiation</literal> dans
+ l'expression SQL <literal>INSERT</literal>. Pour les
entit�s impliqu�es dans
+ un h�ritage mapp�, seules les propri�t�s directement d�finies � ce
niveau de classe
+ donn� peuvent �tre utilis�es dans properties_list. Les propri�t�s de
la classe m�re
+ ne sont pas permises ; et les propri�t�s des classes filles n'ont
pas de sens. En
+ d'autres mots, les expressions
<literal>INSERT</literal> par nature non polymorphiques.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ select_statement peut �tre n'importe quelle requ�te de s�lection
HQl valide, avec
+ l'avertissement que les types de retour doivent correspondre aux
types attendus par
+ l'insertion. Actuellement, c'est v�rifi� durant la
compilation de la requ�te plut�t
+ que la v�rification soit rel�gu�e � la base de donn�es. Notez
cependant que cela
+ pourrait poser des probl�mes entre les
<literal>Type</literal>s d'Hibernate qui
+ sont <emphasis>�quivalents</emphasis> oppos� �
<emphasis>�gaux</emphasis>. Cela
+ pourrait poser des probl�mes avec des disparit�s entre une propri�t�
d�finie
+ comme un <literal>org.hibernate.type.DateType</literal>
et une propri�t� d�finie
+ comme un
<literal>org.hibernate.type.TimestampType</literal>, m�me si la base de
donn�es
+ ne ferait pas de distinction ou ne serait pas capable de g�rer la
conversion.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Pour la propri�te id, l'expression d'insertion vous donne
deux options. Vous
+ pouvez soit sp�cifier explicitement la propri�t� id dans
properties_list
+ (auquel cas sa valeur est extraite de l'expression de s�lection
correspondante),
+ soit l'omettre de properties_list (auquel cas une valeur g�n�r�e
est utilis�e).
+ Cette derni�re option est seulement disponible en utilisant le
g�n�rateur d'identifiant
+ qui op�re dans la base de donn�es ; tenter d'utiliser cette
option avec n'importe quel
+ type de g�n�rateur "en m�moire" causera une exception
durant l'analyse. Notez
+ que pour les buts de cette discussion, les g�n�rateurs "en
base" sont consid�r�s
+ �tre
<literal>org.hibernate.id.SequenceGenerator</literal> (et ses classes filles)
+ et n'importe quelles impl�mentations de
+
<literal>org.hibernate.id.PostInsertIdentifierGenerator</literal>.
+ L'exception la plus notable ici est
<literal>org.hibernate.id.TableHiLoGenerator</literal>,
+ qu ne peut pas �tre utilis�e parce qu'il ne propose pas un moyen
de d'exposer ses valeurs
+ par un select.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Pour des propri�t�s mapp�es comme
<literal>version</literal> ou <literal>timestamp</literal>,
+ l'expression d'insertion vous donne deux options. Vous pouvez
soit sp�cifier la propri�t� dans
+ properties_list (auquel cas sa valeur est extraite des expressions
select correspondantes),
+ soit l'omettre de properties_list (auquel cas la
<literal>valeur de graine</literal>
+ (NdT : seed value) d�finie par le
<literal>org.hibernate.type.VersionType</literal> est utilis�e).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Un exemple d'ex�cution d'une expression
<literal>INSERT</literal> HQL :
+ </para>
+
+ <programlisting><![CDATA[Session session =
sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+
+String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name
from Customer c where ...";
+int createdEntities = s.createQuery( hqlInsert )
+ .executeUpdate();
+tx.commit();
+session.close();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/best_practices.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/best_practices.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/best_practices.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/best_practices.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="best-practices" revision="3">
+ <title>Meilleures pratiques</title>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>D�coupez finement vos classes et mappez les en utilisant
<literal><component></literal>.</term>
+ <listitem>
+ <para>
+ Utilisez une classe <literal>Adresse</literal> pour
encapsuler <literal>Rue</literal>,
+ <literal>Region</literal>,
<literal>CodePostal</literal>.
+ Ceci permet la r�utilisation du code et simplifie la maintenance.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>D�clarez des propri�t�s d'identifiants dans les classes
persistantes.</term>
+ <listitem>
+ <para>
+ Hibernate rend les propri�t�s d'identifiants optionnelles. Il
existe beaucoup de raisons
+ pour lesquelles vous devriez les utiliser. Nous recommandons que vous
utilisiez des identifiants
+ techniques (g�n�r�s, et sans connotation m�tier).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Identifiez les clefs naturelles.</term>
+ <listitem>
+ <para>
+ Identifiez les clefs naturelles pour toutes les entit�s, et mappez
les avec
+ <literal><natural-id></literal>.
Impl�mentez <literal>equals()</literal> et
+ <literal>hashCode()</literal> pour comparer les
propri�t�s qui composent la clef naturelle.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Placez chaque mapping de classe dans son propre
fichier.</term>
+ <listitem>
+ <para>
+ N'utilisez pas un unique document de mapping. Mappez
<literal>com.eg.Foo</literal> dans
+ le fichier <literal>com/eg/Foo.hbm.xml</literal>. Cela
prend tout son sens lors
+ d'un travail en �quipe.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Chargez les mappings comme des ressources.</term>
+ <listitem>
+ <para>
+ D�ployez les mappings en m�me temps que les classes qu'ils
mappent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Pensez � externaliser les cha�nes de caract�res.</term>
+ <listitem>
+ <para>
+ Ceci est une bonne habitude si vos requ�tes appellent des fonctions
SQL qui ne sont
+ pas au standard ANSI. Cette externalisation dans les fichiers de
mapping rendra votre
+ application plus portable.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Utilisez les variables "bind�es".</term>
+ <listitem>
+ <para>
+ Comme en JDBC, remplacez toujours les valeurs non constantes par
"?". N'utilisez jamais
+ la manipulation des cha�nes de caract�res pour remplacer des valeurs
non constantes dans
+ une requ�te ! Encore mieux, utilisez les param�tres nomm�s dans les requ�tes.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Ne g�rez pas vous m�me les connexions JDBC.</term>
+ <listitem>
+ <para>
+ Hibernate laisse l'application g�rer les connexions JDBC. Vous ne
devriez g�rer vos connexions
+ qu'en dernier recours. Si vous ne pouvez pas utiliser les
syst�mes de connexions livr�s,
+ r�fl�chissez � l'id�e de fournir votre propre impl�mentation de
<literal>org.hibernate.connection.ConnectionProvider</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Pensez � utiliser les types utilisateurs.</term>
+ <listitem>
+ <para>
+ Supposez que vous ayez une type Java, de telle biblioth�que, qui a
besoin d'�tre persist� mais
+ qui ne fournit pas les accesseurs n�cessaires pour le mapper comme
composant. Vous devriez
+ impl�menter
+ <literal>org.hibernate.UserType</literal>.Cette approche
lib�re le code de l'application
+ de l'impl�mentation des transformations vers / depuis les types
Hibernate.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Utilisez du JDBC pur dans les goulets
d'�tranglement.</term>
+ <listitem>
+ <para>
+ Dans certaines parties critiques de votre syst�me d'un point de
vue performance, quelques op�rations
+ peuvent tirer partie d'un appel JDBC natif.
+ Mais attendez de <emphasis>savoir</emphasis>
+ que c'est un goulet d'�tranglement. Ne supposez jamais
qu'un appel JDBC sera forc�ment plus
+ rapide. Si vous avez besoin d'utiliser JDBC directement, ouvrez
une <literal>Session</literal>
+ Hibernate et utilisez la connexion SQL sous-jacente. Ainsi vous
pourrez utiliser la m�me strat�gie
+ de transation et la m�me gestion des connexions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Comprendre le flush de
<literal>Session</literal>.</term>
+ <listitem>
+ <para>
+ De temps en temps la Session synchronise ses �tats persistants avec
la base de donn�es.
+ Les performances seront affect�es si ce processus arrive trop
souvent. Vous pouvez parfois
+ minimiser les flush non n�cessaires en d�sactivant le flush
automatique ou m�me en changeant
+ l'ordre des op�rations men�es dans une transaction particuli�re.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Dans une architecture � trois couches, pensez � utiliser
<literal>saveOrUpdate()</literal>.</term>
+ <listitem>
+ <para>
+ Quand vous utilisez une architecture � base de servlet / session
bean, vous pourriez passer
+ des objets charg�s dans le bean session vers et depuis la couche
servlet / JSP. Utilisez
+ une nouvelle session pour traiter chaque requ�te.
+ Utilisez <literal>Session.merge()</literal> ou
<literal>Session.saveOrUpdate()</literal> pour
+ synchroniser les objets avec la base de donn�es.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Dans une architecture � deux couches, pensez � utiliser la
d�connexion de session.</term>
+ <listitem>
+ <para>
+ Les transactions de bases de donn�es doivent �tre aussi courtes que
possible
+ pour une meilleure mont�e en charge.Cependant, il est souvent
n�cessaire d'impl�menter
+ de longues <emphasis>transactions
applicatives</emphasis>, une simple unit� de travail du point de vue de
+ l'utilisateur. Une transaction applicative
+ peut s'�taler sur plusieurs cycles de requ�tes/r�ponses du
client.
+ Il est commun d'utiliser des objets d�tach�s pour impl�menter des
transactions applicatives.
+ Une alternative, extr�mement appropri�e dans une architecture � 2
couches, est de
+ maintenir un seul contact de persistance ouvert (session) pour toute
la dur�e de vie
+ de la transaction applicative et simplement se d�connecter de la
connexion JDBC � la fin de chaque requ�te,
+ et se reconnecter au d�but de la requ�te suivante. Ne partagez jamais
une seule
+ session avec plus d'une transaction applicative, ou vous
travaillerez avec des
+ donn�es p�rim�es.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Consid�rez que les exceptions ne sont pas
rattrapables.</term>
+ <listitem>
+ <para>
+ Il s'agit plus d'une pratique obligatoire que d'une
"meilleure pratique". Quand une exception
+ intervient, il faut faire un rollback de la
<literal>Transaction</literal> et
+ fermer la <literal>Session</literal>.
+ Sinon, Hibernate ne peut garantir l'int�grit� des �tats
persistants en m�moire. En particulier,
+ n'utilisez pas <literal>Session.load()</literal> pour
d�terminer si une instance avec un identifiant
+ donn� existe en base de donn�es, utilisez
<literal>Session.get()</literal> ou un requ�te.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Pr�f�rez le chargement tardif des associations.</term>
+ <listitem>
+ <para>
+ Utilisez le chargement complet avec mod�ration.
+ Utilisez les proxies et les collections charg�es tardivement
+ pour la plupart des associations vers des classes qui ne sont pas
susceptibles
+ d'�tre compl�tement retenues dans le cache de second niveau.
+ Pour les assocations de classes en cache, o� il y a une extr�mement
+ forte probabilit� que l'�l�ment soit en cache, d�sactivez
explicitement le chargement
+ par jointures ouvertes en utilisant
<literal>outer-join="false"</literal>.
+ Lorsqu'un chargement par jointure ouverte est appropri� pour un
cas d'utilisation
+ particulier, utilisez une requ�te avec un <literal>left join
fetch</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ Utilisez le pattern <emphasis>d'une ouverture de session dans
une vue</emphasis>,
+ ou une <emphasis>phase d'assemblage</emphasis>
disciplin�e pour �viter des probl�mes
+ avec des donn�es non rapatri�es.
+ </term>
+ <listitem>
+ <para>
+ Hibernate lib�re les d�veloppeurs de l'�criture fastidieuse des
<emphasis>objets de transfert
+ de donn�es (NdT : Data Transfer Objects)</emphasis> (DTO). Dans
une architecture EJB traditionnelle,
+ les DTOs ont deux buts : premi�rement, ils contournent le probl�me
des "entity bean" qui ne sont pas
+ s�rialisables ; deuxi�mement, ils d�finissent implicitement une phase
d'assemblage o� toutes les
+ donn�es utilis�es par la vue sont rapatri�es et organis�es dans les
DTOs avant de retourner sous le
+ contr�le de la couche de pr�sentation. Hibernate �limine le premier
but. Pourtant, vous aurez encore
+ besoin d'une phase d'assemblage (pensez vos m�thodes m�tier
comme ayant un contrat strict avec la
+ couche de pr�sentation � propos de quelles donn�es sont disponibles
dans les objets d�tach�s)
+ � moins que vous soyez pr�par�s � garder le contexte de
+ persistance (la session) ouvert � travers tout le processus de rendu
de la vue.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Pensez � abstraite votre logique m�tier
d'Hibernate.</term>
+ <listitem>
+ <para>
+ Cachez le m�canisme d'acc�s aux donn�es (Hibernate) derri�re une
interface. Combinez les patterns
+ <emphasis>DAO</emphasis> et <emphasis>Thread Local
Session</emphasis>. Vous pouvez m�me avoir quelques
+ classes persist�es par du JDBC pur, associ�es � Hibernate via un
<literal>UserType</literal> (ce conseil est
+ valable pour des applications de taille respectables ; il n'est
pas valable pour une application
+ avec cinq tables).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>N'utilisez pas d'associations de mapping
exotiques.</term>
+ <listitem>
+ <para>
+ De bons cas d'utilisation pour de vraies associations
plusieurs-vers-plusieurs
+ sont rares. La plupart du temps vous avez besoin d'informations
additionnelles
+ stock�es dans la table d'association.
+ Dans ce cas, il est pr�f�rable d'utiliser deux associations
un-vers-plusieurs vers une classe
+ de liaisons interm�diaire. En fait, nous pensons que la plupart des
associations sont
+ de type un-vers-plusieurs ou plusieurs-vers-un, vous devez �tre tr�s
attentifs lorsque
+ vous utilisez autre chose et vous demander si c'est vraiment
n�cessaire.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Pr�f�rez les associations bidirectionnelles.</term>
+ <listitem>
+ <para>
+ Les associations unidirectionnelles sont plus difficiles �
questionner.
+ Dans une grande application, la plupart des associations devraient
�tre navigables dans les deux directions dans les requ�tes.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</chapter>
+
Copied:
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/collection_mapping.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/collection_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/collection_mapping.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/collection_mapping.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,1216 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="collections">
+ <title>Mapping des collections</title>
+
+ <sect1 id="collections-persistent" revision="3">
+ <title>Collections persistantes</title>
+
+ <para>
+ Hibernate requiert que les champs contenant des collections persistantes
soient d�clar�s
+ comme des types d'interface, par exemple :
+ </para>
+
+ <programlisting><![CDATA[public class Product {
+ private String serialNumber;
+ private Set parts = new HashSet();
+
+ public Set getParts() { return parts; }
+ void setParts(Set parts) { this.parts = parts; }
+ public String getSerialNumber() { return serialNumber; }
+ void setSerialNumber(String sn) { serialNumber = sn; }
+}]]></programlisting>
+
+ <para>
+ L'interface r�elle devrait �tre
<literal>java.util.Set</literal>,
+ <literal>java.util.Collection</literal>,
<literal>java.util.List</literal>,
+ <literal>java.util.Map</literal>,
<literal>java.util.SortedSet</literal>,
+ <literal>java.util.SortedMap</literal> ou ... n'importe quoi
d'autre ! (O�
+ "n'importe quoi d'autre" signifie que vous devrez �crire
une impl�mentation de
+ <literal>org.hibernate.usertype.UserCollectionType</literal>.)
+ </para>
+
+ <para>
+ Notez comment nous avons initialis� les variables d'instance avec une
instance de
+ <literal>HashSet</literal>. C'est le meilleur moyen pour
initialiser les
+ collections d'instances nouvellement cr��es (non persistantes). Quand
+ nous fabriquons l'instance persistante - en appelant
<literal>persist()</literal>,
+ par exemple - Hibernate remplacera r�ellement le
<literal>HashSet</literal>
+ avec une instance d'une impl�mentation propre � Hibernate de
<literal>Set</literal>.
+ Prenez garde aux erreurs :
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new DomesticCat();
+Cat kitten = new DomesticCat();
+....
+Set kittens = new HashSet();
+kittens.add(kitten);
+cat.setKittens(kittens);
+session.persist(cat);
+kittens = cat.getKittens(); // Ok, la collection kittens est un Set
+(HashSet) cat.getKittens(); // Erreur !]]></programlisting>
+
+ <para>
+ Les collections persistantes inject�es par Hibernate se comportent de la m�me
mani�re que
+ <literal>HashMap</literal>,
<literal>HashSet</literal>,
+ <literal>TreeMap</literal>,
<literal>TreeSet</literal> ou
+ <literal>ArrayList</literal>, selon le type de l'interface.
+ </para>
+
+ <para>
+ Les instances des collections ont le comportement habituel des types des
valeurs.
+ Elles sont automatiquement persist�es quand elles sont r�f�renc�es par un
objet persistant et
+ automatiquement effac�es quand elles sont d�r�f�renc�es. Si une collection
est pass�e
+ d'un objet persistant � un autre, ses �l�ments pourraient �tre d�plac�s
d'une table
+ � une autre. Deux entit�s ne peuvent pas partager une r�f�rence vers une m�me
instance
+ d'une collection. D� au mod�le relationnel sous-jacent, les propri�t�s
contenant des
+ collections ne supportent pas la s�mantique de la valeur null ; Hibernate ne
distingue pas
+ une r�f�rence vers une collection nulle d'une collection vide.
+ </para>
+
+ <para>
+ Vous ne devriez pas vous pr�occuper trop de �a. Utilisez les collections
persistantes de
+ la m�me mani�re que vous utilisez des collections Java ordinaires.
Assurez-vous
+ de comprendre la s�mantique des associations bidirectionnelles (trait�e plus
loin).
+ </para>
+
+ </sect1>
+
+ <sect1 id="collections-mapping" revision="4">
+ <title>Mapper une collection</title>
+
+ <para>
+ L'�l�ment de mapping d'Hibernate utilis� pour mapper une collection
d�pend du type de
+ l'interface. Par exemple, un �l�ment
<literal><set></literal> est utilis�
+ pour mapper des propri�t�s de type <literal>Set</literal>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Product">
+ <id name="serialNumber" column="productSerialNumber"/>
+ <set name="parts">
+ <key column="productSerialNumber" not-null="true"/>
+ <one-to-many class="Part"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ � part <literal><set></literal>, il y aussi les
�l�ments de mapping
+ <literal><list></literal>,
<literal><map></literal>,
+ <literal><bag></literal>,
<literal><array></literal> et
+ <literal><primitive-array></literal>.
+ L'�l�ment <literal><map></literal> est
repr�sentatif :
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="mappingcollection1" coords="2 65"/>
+ <area id="mappingcollection2" coords="3 65"/>
+ <area id="mappingcollection3" coords="4 65"/>
+ <area id="mappingcollection4" coords="5 65"/>
+ <area id="mappingcollection5" coords="6 65"/>
+ <area id="mappingcollection6" coords="7 65"/>
+ <area id="mappingcollection7" coords="8 65"/>
+ <area id="mappingcollection8" coords="9 65"/>
+ <area id="mappingcollection9" coords="10 65"/>
+ <area id="mappingcollection10" coords="11
65"/>
+ <area id="mappingcollection11" coords="12
65"/>
+ <area id="mappingcollection12" coords="13
65"/>
+ <area id="mappingcollection13" coords="14
65"/>
+ <area id="mappingcollection14" coords="15
65"/>
+ </areaspec>
+ <programlisting><![CDATA[<map
+ name="nomDePropriete"
+ table="nom_de_table"
+ schema="nom_du_schema"
+ lazy="true|extra|false"
+ inverse="true|false"
+ cascade="all|none|save-update|delete|all-delete-orphan"
+ sort="unsorted|natural|ClasseDeComparateur"
+ order-by="nom_de_column asc|desc"
+ where="condition sql where quelcconque"
+ fetch="join|select|subselect"
+ batch-size="N"
+ access="field|property|NomDeClasse"
+ optimistic-lock="true|false"
+ mutable="true|false"
+ node="nom-d-element|."
+ embed-xml="true|false"
+>
+
+ <key .... />
+ <map-key .... />
+ <element .... />
+</map>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mappingcollection1">
+ <para>
+ <literal>name</literal> : le nom de la propri�t�
contenant la collection
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection2">
+ <para>
+ <literal>table</literal> (optionnel - par d�faut =
nom de la propri�t�) : le
+ nom de la table de la collection (non utilis� pour les
associations one-to-many)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection3">
+ <para>
+ <literal>schema</literal> (optionnel) : le nom du
sch�ma pour surcharger le
+ sch�ma d�clar� dans l'�l�ment racine
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection4">
+ <para>
+ <literal>lazy</literal> (optionnel - par d�faut =
<literal>true</literal>) :
+ peut �tre utilis� pour d�sactiver l'initialisation tardive et
sp�cifier
+ que l'association est toujours rapport�e, ou pour activer la
+ r�cup�ration extra-paresseuse (NdT : extra-lazy) o� la plupart
des
+ op�rations n'initialisent pas la collection (appropri� pour
de tr�s
+ grosses collections)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection5">
+ <para>
+ <literal>inverse</literal> (optionnel - par d�faut =
<literal>false</literal>) :
+ d�finit cette collection comme l'extr�mit�
"inverse" de l'association
+ bidirectionnelle
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection6">
+ <para>
+ <literal>cascade</literal> (optionnel - par d�faut =
<literal>none</literal>) :
+ active les op�rations de cascade vers les entit�s filles
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection7">
+ <para>
+ <literal>sort</literal> (optionnel) : sp�cifie une
collection tri�e via un ordre
+ de tri <literal>naturel</literal>, ou via une classe
comparateur donn�e (impl�mentant Comparator)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection8">
+ <para>
+ <literal>order-by</literal> (optionnel, seulement �
partir du JDK1.4) :
+ sp�cifie une colonne de table
+ (ou des colonnes) qui d�finit l'ordre d'it�ration de
<literal>Map</literal>, <literal>Set</literal>
+ ou Bag, avec en option <literal>asc</literal> ou
<literal>desc</literal>
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection9">
+ <para>
+ <literal>where</literal> (optionnel) : sp�cifie une
condition SQL arbitraire <literal>WHERE</literal>
+ � utiliser au chargement ou � la suppression d'une collection
(utile si la collection
+ ne doit contenir qu'un sous ensemble des donn�es
disponibles)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection10">
+ <para>
+ <literal>fetch</literal> (optionnel, par d�faut =
<literal>select</literal>) :
+ � choisir entre r�cup�ration par jointures externes, r�cup�ration
par
+ selects s�quentiels, et r�cup�ration par sous-selects
s�quentiels
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection11">
+ <para>
+ <literal>batch-size</literal> (optionnel, par d�faut
= <literal>1</literal>) : une taille
+ de batch (batch size) utilis�e pour charger plusieurs instances
de cette collection en
+ initialisation tardive
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection12">
+ <para>
+ <literal>access</literal> (optionnel - par d�faut =
<literal>property</literal>) : La
+ strat�gie qu'Hibernate doit utiliser pour acc�der � la valeur
de la propri�t�
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection13">
+ <para>
+ <literal>optimistic-lock</literal> (optionnel - par
d�faut = <literal>true</literal>) :
+ sp�cifie que changer l'�tat de la collection entra�ne
l'incr�mentation
+ de la version appartenant � l'entit� (Pour une association un
vers plusieurs,
+ il est souvent raisonnable de d�sactiver ce param�tre)
+ </para>
+ </callout>
+ <callout arearefs="mappingcollection14">
+ <para>
+ <literal>mutable</literal> (optionnel - par d�faut =
<literal>true</literal>) :
+ une valeur � <literal>false</literal> sp�cifie que
les �l�ments de la
+ collection ne changent jamais (une optimisation mineure dans
certains cas)
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <sect2 id="collections-foreignkeys" >
+ <title>Les clefs �trang�res d'une collection</title>
+
+ <para>
+ Les instances d'une collection sont distingu�es dans la base par la
clef �trang�re
+ de l'entit� qui poss�de la collection. Cette clef �trang�re est
r�f�renc�e comme la(es)
+ <emphasis>colonne(s) de la clef de la collection</emphasis>
de la table de la collection.
+ La colonne de la clef de la collection est mapp�e par l'�l�ment
<literal><key></literal>.
+ </para>
+
+ <para>
+ Il peut y avoir une contrainte de nullit� sur la colonne de la clef
�trang�re. Pour les
+ associations unidirectionnelles un vers plusieurs, la colonne de la clef
�trang�re
+ peut �tre nulle par d�faut, donc vous pourriez avoir besoin de sp�cifier
+ <literal>not-null="true"</literal>.
+ </para>
+
+ <programlisting><![CDATA[<key
column="productSerialNumber"
not-null="true"/>]]></programlisting>
+
+ <para>
+ La contraite de la clef �trang�re peut utiliser <literal>ON DELETE
CASCADE</literal>.
+ </para>
+
+ <programlisting><![CDATA[<key
column="productSerialNumber"
on-delete="cascade"/>]]></programlisting>
+
+ <para>
+ Voir le chapitre pr�c�dent pour une d�finition compl�te de l'�l�ment
<literal><key></literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-elements" >
+ <title>Les �l�ments d'une collection</title>
+
+ <para>
+ Les collections peuvent contenir la plupart des autres types Hibernate,
dont tous les types
+ basiques, les types utilisateur, les composants, et bien s�r, les
r�f�rences vers
+ d'autres entit�s. C'est une distinction importante : un objet
dans une collection
+ pourrait �tre g�r� avec une s�mantique de "valeur" (sa dur�e de
vie d�pend compl�tement
+ du propri�taire de la collection) ou il pourrait avoir une r�f�rence vers
une autre
+ entit�, avec sa propre dur�e de vie. Dans le dernier cas, seul le
"lien" entre les 2 objets
+ est consid�r� �tre l'�tat retenu par la collection.
+ </para>
+
+ <para>
+ Le type contenu est r�f�renc� comme le <emphasis>type de
l'�l�ment de la collection</emphasis>.
+ Les �l�ments de la collections sont mapp�s par
<literal><element></literal> ou
+ <literal><composite-element></literal>, ou dans
le cas des r�f�rences d'entit�, avec
+ <literal><one-to-many></literal> ou
<literal><many-to-many></literal>.
+ Les deux premiers mappent des �l�ments avec un s�mantique de valeur, les
deux suivants sont
+ utilis�s pour mapper des associations d'entit�.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexed">
+ <title>Collections index�es</title>
+
+ <para>
+ Tous les mappings de collection, except�s ceux avec les s�mantiques
d'ensemble (NdT : set) et
+ de sac (NdT : bag), ont besoin d'une <emphasis>colonne
d'index</emphasis> dans la
+ table de la collection - une colonne qui mappe un index de tableau, ou un
index de
+ <literal>List</literal>, ou une clef de
<literal>Map</literal>. L'index d'une
+ <literal>Map</literal> peut �tre n'importe quel type
basique, mapp� avec
+ <literal><map-key></literal>, �a peut �tre une
r�f�rence d'entit� mapp�e avec
+ <literal><map-key-many-to-many></literal>, ou
�a peut �tre un type compos�, mapp� avec
+ <literal><composite-map-key></literal>.
L'index d'un tableau ou d'une liste est toujours
+ de type <literal>integer</literal> et est mapp� en utilisant
l'�l�ment <literal><list-index></literal>.
+ Les colonnes mapp�es contiennent des entiers s�quentiels (num�rot�s �
partir de z�ro par d�faut).
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="index1" coords="2 45"/>
+ <area id="index2" coords="3 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<list-index
+ column="nom_de_colonne"
+ base="0|1|..."/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="index1">
+ <para>
+ <literal>nom_de_colonne</literal> (requis) : le nom
de la colonne contenant les valeurs de l'index de la collection
+ </para>
+ </callout>
+ <callout arearefs="index1">
+ <para>
+ <literal>base</literal> (optionnel, par d�faut =
<literal>0</literal>) : la valeur
+ de la colonne de l'index qui correspond au premier �l�ment de
la liste ou du tableau
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="mapkey1" coords="2 45"/>
+ <area id="mapkey2" coords="3 45"/>
+ <area id="mapkey3" coords="4 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key
+ column="nom_de_colonne"
+ formula="n'importe quelle expression SQL"
+ type="nom_du_type"
+ node="@nom-d-attribut"
+ length="N"/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="mapkey1">
+ <para>
+ <literal>column</literal> (optionnel) :
+ le nom de la colonne contenant les valeurs de l'index de la
collection
+ </para>
+ </callout>
+ <callout arearefs="mapkey2">
+ <para>
+ <literal>formula</literal> (optionnel) :
+ une formule SQL utilis�e pour �valuer la clef de la map
+ </para>
+ </callout>
+ <callout arearefs="mapkey3">
+ <para>
+ <literal>type</literal> (reguis): le type des clefs
de la map
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <programlistingco>
+ <areaspec>
+ <area id="indexmanytomany1" coords="2 45"/>
+ <area id="indexmanytomany2" coords="3 45"/>
+ <area id="indexmanytomany3" coords="3 45"/>
+ </areaspec>
+ <programlisting><![CDATA[<map-key-many-to-many
+ column="nom_de_colonne"
+ formula="n'importe quelle expression SQL"
+ class="NomDeClasse"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="indexmanytomany1">
+ <para>
+ <literal>column</literal> (optionnel) :
+ le nom de la colonne de la clef �trang�re pour les valeurs de
l'index de la collection
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany2">
+ <para>
+ <literal>formula</literal> (optionnel) :
+ une formulre SQL utilis�e pour �valuer la clef �trang�re de la
clef de la map
+ </para>
+ </callout>
+ <callout arearefs="indexmanytomany3">
+ <para>
+ <literal>class</literal> (requis): la classe de
l'entit� utilis�e comme clef de la map
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+ <para>
+ Si votre table n'a pas de colonne d'index, et que vous souhaitez
tout de m�me utiliser
+ <literal>List</literal> comme type de propri�t�, vous devriez
mapper la propri�t� comme un
+ <emphasis><bag></emphasis> Hibernate. Un sac
(NdT : bag) ne garde pas son ordre quand
+ il est r�cup�r� de la base de donn�es, mais il peut �tre optionnellement
tri� ou ordonn�.
+ </para>
+
+ </sect2>
+
+ <para>
+ Il y a pas mal de vari�t�s de mappings qui peuvent �tre g�n�r�s pour les
collections,
+ couvrant beaucoup des mod�les relationnels communs. Nous vous sugg�rons
d'exp�rimenter avec l'outil de
+ g�n�ration de sch�ma pour avoir une id�e de comment traduire les diff�rentes
d�clarations de mapping vers des table de la base de donn�es.
+ </para>
+
+ <sect2 id="collections-ofvalues" revision="2">
+ <title>Collections de valeurs et associations
plusieurs-vers-plusieurs</title>
+
+ <para>
+ N'importe quelle collection de valeurs ou association
plusieurs-vers-plusieurs requiert une
+ <emphasis>table de collection</emphasis> avec une(des) colonne(s)
de clef �trang�re, une(des)
+ <emphasis>colonne(s) d'�l�ment de la collection</emphasis> ou
des colonnes et possiblement
+ une(des) colonne(s) d'index.
+ </para>
+
+ <para>
+ Pour une collection de valeurs, nous utilisons la balise
<literal><element></literal>.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="element1b" coords="2 50"/>
+ <area id="element2b" coords="3 50"/>
+ <area id="element3b" coords="4 50"/>
+ </areaspec>
+ <programlisting><![CDATA[<element
+ column="nom_de_colonne"
+ formula="n'importe quelle expression SQL"
+ type="nomDeType"
+ length="L"
+ precision="P"
+ scale="S"
+ not-null="true|false"
+ unique="true|false"
+ node="nom-d-element"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="element1b">
+ <para>
+ <literal>column</literal> (optionnel) : le nom de la
colonne contenant les valeurs de l'�l�ment de la collection
+ </para>
+ </callout>
+ <callout arearefs="element2b">
+ <para>
+ <literal>formula</literal> (optionnel) : une formule
SQL utilis�e pour �valuer l'�l�ment
+ </para>
+ </callout>
+ <callout arearefs="element3b">
+ <para>
+ <literal>type</literal> (requis) : le type de
l'�l�ment de la collection
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Une <emphasis>association plusieurs-vers-plusieurs</emphasis> est
sp�cifi�e en
+ utilisant l'�l�ment
<literal><many-to-many></literal>.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="manytomany1" coords="2 60"/>
+ <area id="manytomany2" coords="3 60"/>
+ <area id="manytomany3" coords="4 60"/>
+ <area id="manytomany4" coords="5 60"/>
+ <area id="manytomany5" coords="6 60"/>
+ <area id="manytomany6" coords="7 60"/>
+ <area id="manytomany7" coords="8 60"/>
+ <area id="manytomany8" coords="9 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<many-to-many
+ column="nom_de_colonne"
+ formula="n'importe quelle expression SQL"
+ class="NomDeClasse"
+ fetch="select|join"
+ unique="true|false"
+ not-found="ignore|exception"
+ entity-name="NomDEntite"
+ property-ref="nomDeProprieteDeLaClasseAssociee"
+ node="nom-d-element"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="manytomany1">
+ <para>
+ <literal>column</literal> (optionnel) : le nom de la
colonne de la clef �trang�re de l'�l�ment
+ </para>
+ </callout>
+ <callout arearefs="manytomany2">
+ <para>
+ <literal>formula</literal> (optionnel) :
+ une formule SQL utilis�e pour �valuer la valeur de la clef
�trang�re de l'�l�ment
+ </para>
+ </callout>
+ <callout arearefs="manytomany3">
+ <para>
+ <literal>class</literal> (requis) : le nom de la
classe associ�e
+ </para>
+ </callout>
+ <callout arearefs="manytomany4">
+ <para>
+ <literal>fetch</literal> (optionnel - par d�faut
<literal>join</literal>) :
+ active les r�cup�rations par jointures externes ou par selects
s�quentiels pour cette association.
+ C'est un cas sp�cial ; pour une r�cup�ration compl�te sans
attente (dans un seul <literal>SELECT</literal>) d'une
+ entit� et de ses relations plusieurs-vers-plusieurs vers
d'autres entit�s,
+ vous devriez activer la r�cup�ration
<literal>join</literal> non seulement sur
+ la collection elle-m�me, mais aussi avec cet attribut sur
l'�l�ment imbriqu�
+ <literal><many-to-many></literal>.
+ </para>
+ </callout>
+ <callout arearefs="manytomany5">
+ <para>
+ <literal>unique</literal> (optionnel) : activer la
g�n�ration DDL d'une
+ contrainte d'unicit� pour la colonne de la clef �trang�re. �a
rend la pluralit�
+ de l'association effectivement un-vers-plusieurs.
+ </para>
+ </callout>
+ <callout arearefs="manytomany6">
+ <para>
+ <literal>not-found</literal> (optionnel - par d�faut
<literal>exception</literal>) :
+ sp�cifie comment les clefs �trang�res qui r�f�rencent la
lignes
+ manquantes seront g�r�es :
<literal>ignore</literal> traitera
+ une ligne manquante comme une association nulle.
+ </para>
+ </callout>
+ <callout arearefs="manytomany7">
+ <para>
+ <literal>entity-name</literal> (optionnel) : le nom
de l'entit� de la classe associ�e, comme une alternative �
<literal>class</literal>
+ </para>
+ </callout>
+ <callout arearefs="manytomany8">
+ <para>
+ <literal>property-ref</literal> (optionnel) : le nom
d'une propri�t� de
+ la classe associ�e qui est jointe � cette clef �trang�re. Si non
sp�cifi�e,
+ la clef primaire de la classe associ�e est utilis�e.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Quelques exemples, d'abord, un ensemble de cha�nes de caract�res :
+ </para>
+
+ <programlisting><![CDATA[<set name="names"
table="person_names">
+ <key column="person_id"/>
+ <element column="person_name" type="string"/>
+</set>]]></programlisting>
+
+ <para>
+ Un bag contenant des entiers (avec un ordre d'it�ration d�termin� par
l'attribut <literal>order-by</literal>) :
+ </para>
+
+ <programlisting><![CDATA[<bag name="sizes"
+ table="item_sizes"
+ order-by="size asc">
+ <key column="item_id"/>
+ <element column="size" type="integer"/>
+</bag>]]></programlisting>
+
+ <para>
+ Un tableau d'entit�s - dans ce cas, une association
plusieurs-vers-plusieurs :
+ </para>
+
+ <programlisting><![CDATA[<array name="addresses"
+ table="PersonAddress"
+ cascade="persist">
+ <key column="personId"/>
+ <list-index column="sortOrder"/>
+ <many-to-many column="addressId" class="Address"/>
+</array>]]></programlisting>
+
+ <para>
+ Une map de cha�nes de caract�res vers des dates :
+ </para>
+
+ <programlisting><![CDATA[<map name="holidays"
+ table="holidays"
+ schema="dbo"
+ order-by="hol_name asc">
+ <key column="id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ Une liste de composants (discute dans le prochain chapitre) :
+ </para>
+
+ <programlisting><![CDATA[<list name="carComponents"
+ table="CarComponents">
+ <key column="carId"/>
+ <list-index column="sortOrder"/>
+ <composite-element class="CarComponent">
+ <property name="price"/>
+ <property name="type"/>
+ <property name="serialNumber" column="serialNum"/>
+ </composite-element>
+</list>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-onetomany">
+ <title>Association un-vers-plusieurs</title>
+
+ <para>
+ Une <emphasis>association un vers plusieurs</emphasis> lie les
tables de deux classes
+ par une clef �trang�re, sans l'intervention d'une table de
collection. Ce mapping perd certaines s�mantiques des collections Java normales :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Une instance de la classe de l'entit� contenue ne peut pas
appartenir � plus d'une
+ instance de la collection
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Une instance de la classe de l'entit� contenue ne peut pas
appara�tre plus plus d'une valeur d'index de la collection
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Une association de <literal>Product</literal> vers
<literal>Part</literal> requiert l'existence d'une
+ clef �trang�re et possiblement une colonne d'index pour la table
<literal>Part</literal>. Une balise
+ <literal><one-to-many></literal> indique que
c'est une association un vers plusieurs.
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="onetomany1" coords="2 60"/>
+ <area id="onetomany2" coords="3 60"/>
+ <area id="onetomany3" coords="4 60"/>
+ </areaspec>
+ <programlisting><![CDATA[<one-to-many
+ class="NomDeClasse"
+ not-found="ignore|exception"
+ entity-name="NomDEntite"
+ node="nom-d-element"
+ embed-xml="true|false"
+ />]]></programlisting>
+ <calloutlist>
+ <callout arearefs="onetomany1">
+ <para>
+ <literal>class</literal> (requis) : le nom de la
classe associ�e
+ </para>
+ </callout>
+ <callout arearefs="onetomany2">
+ <para>
+ <literal>not-found</literal> (optionnel - par d�faut
<literal>exception</literal>) :
+ sp�cifie comment les identifiants cach�s qui r�f�rencent des
lignes manquantes seront g�r�s :
+ <literal>ignore</literal> traitera une ligne
manquante comme une association nulle
+ </para>
+ </callout>
+ <callout arearefs="onetomany3">
+ <para>
+ <literal>entity-name</literal> (optionnel) : le nom
de l'entit� de la
+ classe associ�e, comme une alternative �
<literal>class</literal>.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Notez que l'�l�ment
<literal><one-to-many></literal> n'a pas besoin de d�clarer
de colonnes. Il n'est pas non plus n�cessaire de sp�cifier le nom de la table nulle
part.
+ </para>
+
+ <para>
+ <emphasis>Note tr�s importante :</emphasis> si la colonne de la
clef d'une association
+ <literal><one-to-many></literal> est d�clar�e
<literal>NOT NULL</literal>, vous devez d�clarer le
+ mapping de <literal><key></literal> avec
<literal>not-null="true"</literal> ou
+ <emphasis>utiliser une association bidirectionnelle</emphasis>
avec le mapping de la
+ collection marqu� <literal>inverse="true"</literal>.
Voir la discussion sur les associations bidirectionnelles plus tard dans ce chapitre.
+ </para>
+
+ <para>
+ Cet exemple montre une map d'entit�s <literal>Part</literal>
par nom (o�
+ <literal>partName</literal> est une propri�t� persistante de
<literal>Part</literal>).
+ Notez l'utilisation d'un index bas� sur une formule.
+ </para>
+
+ <programlisting><![CDATA[<map name="parts"
+ cascade="all">
+ <key column="productId" not-null="true"/>
+ <map-key formula="partName"/>
+ <one-to-many class="Part"/>
+</map>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="collections-advancedmappings">
+ <title>Mappings de collection avanc�s</title>
+
+ <sect2 id="collections-sorted" revision="2">
+ <title>Collections tri�es</title>
+
+ <para>
+ Hibernate supporte des collections impl�mentant
<literal>java.util.SortedMap</literal> et
+ <literal>java.util.SortedSet</literal>. Vous devez sp�cifier un
comparateur dans le fichier de mapping :
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases"
+ table="person_aliases"
+ sort="natural">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" sort="my.custom.HolidayComparator">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ Les valeurs permises pour l'attribut <literal>sort</literal>
sont <literal>unsorted</literal>,
+ <literal>natural</literal> et le nom d'une classe
impl�mentant
+ <literal>java.util.Comparator</literal>.
+ </para>
+
+ <para>
+ Les collections tri�es se comportent r�ellement comme
<literal>java.util.TreeSet</literal> ou
+ <literal>java.util.TreeMap</literal>.
+ </para>
+
+ <para>
+ Si vous voulez que la base de donn�es elle-m�me ordonne les �l�ments de la
collection, utilisez l'attribut
+ <literal>order-by</literal> des mappings
<literal>set</literal>, <literal>bag</literal>
+ ou <literal>map</literal>. Cette solution est seulement
disponible � partir du JDK 1.4 (c'est
+ impl�ment� en utilisant <literal>LinkedHashSet</literal> ou
+ <literal>LinkedHashMap</literal>). Ceci ex�cute le tri dans la
requ�te SQL, pas en m�moire.
+ </para>
+
+ <programlisting><![CDATA[<set name="aliases"
table="person_aliases" order-by="lower(name) asc">
+ <key column="person"/>
+ <element column="name" type="string"/>
+</set>
+
+<map name="holidays" order-by="hol_date, hol_name">
+ <key column="year_id"/>
+ <map-key column="hol_name" type="string"/>
+ <element column="hol_date type="date"/>
+</map>]]></programlisting>
+
+ <para>
+ Notez que la valeur de l'attribut <literal>order-by</literal>
est un ordre SQL, pas un ordre HQL !
+ </para>
+
+ <para>
+ Les associations peuvent m�me �tre tri�es sur des crit�res arbitraires �
l'ex�cution en utilisant un <literal>filter()</literal> de collection.
+ </para>
+
+ <programlisting><![CDATA[sortedUsers = s.createFilter( group.getUsers(),
"order by this.name" ).list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="collections-bidirectional" revision="1">
+ <title>Associations bidirectionnelles</title>
+
+ <para>
+ Une <emphasis>association bidirectionnelle</emphasis> permet une
navigation �
+ partir de la "fin" de l'association. Deux sortes
d'associations bidirectionnelles sont support�es :
+ <variablelist>
+ <varlistentry>
+ <term>un-vers-plusieurs (NdT : one-to-many)</term>
+ <listitem>
+ <para>
+ ensemble ou sac � une extr�mit�, une seule valeur �
l'autre
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>plusieurs-vers-plusieurs (NdT :
many-to-many)</term>
+ <listitem>
+ <para>
+ ensemble ou sac aux deux extr�mit�s
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Vous pouvez sp�cifier une association plusieurs-vers-plusieurs
bidirectionnelle simplement
+ en mappant deux associations plusieurs-vers-plusieurs vers la m�me table de
base de donn�es et en d�clarant une extr�mit� comme
<emphasis>inverse</emphasis> (celle de votre choix, mais �a ne peut pas �tre
une collection index�e).
+ </para>
+
+ <para>
+ Voici un exemple d'association bidirectionnelle plusieurs-vers-plusieurs
; chaque cat�gorie peut
+ avoir plusieurs objets et chaque objet peut �tre dans plusieurs cat�gories :
+ </para>
+
+ <programlisting><![CDATA[<class name="Category">
+ <id name="id" column="CATEGORY_ID"/>
+ ...
+ <bag name="items" table="CATEGORY_ITEM">
+ <key column="CATEGORY_ID"/>
+ <many-to-many class="Item" column="ITEM_ID"/>
+ </bag>
+</class>
+
+<class name="Item">
+ <id name="id" column="ITEM_ID"/>
+ ...
+
+ <!-- inverse end -->
+ <bag name="categories" table="CATEGORY_ITEM"
inverse="true">
+ <key column="ITEM_ID"/>
+ <many-to-many class="Category" column="CATEGORY_ID"/>
+ </bag>
+</class>]]></programlisting>
+
+ <para>
+ Les changements faits uniquement sur l'extr�mint� inverse de
l'association <emphasis>ne sont pas</emphasis>
+ persist�s. Ceci signifie qu'Hibernate a deux repr�sentations en m�moire
pour chaque
+ association bidirectionnelles, un lien de A vers B et un autre de B vers A.
C'est
+ plus facile � comprendre si vous pensez au mod�le objet de Java et comment
nous
+ cr�ons une relation plusieurs-vers-plusieurs en Java :
+ </para>
+
+ <programlisting><![CDATA[
+category.getItems().add(item); // La cat�gorie est maintenant "au
courant" de la relation
+item.getCategories().add(category); // L'objet est maintenant "au
courant" de la relation
+
+session.persist(item); // La relation ne sera pas sauvegard�e !
+session.persist(category); // La relation sera
sauvegard�e]]></programlisting>
+
+ <para>
+ La partie non-inverse est utilis�e pour sauvegarder la repr�sentation en
m�moire dans la base de donn�es.
+ </para>
+
+ <para>
+ Vous pouvez d�finir une association un-vers-plusieurs bidirectionnelle en
mappant une
+ association un-vers-plusieurs vers la(es) m�me(s) colonne(s) de table
qu'une association
+ plusieurs-vers-un et en d�clarant l'extr�mit� pluri-valu�e
<literal>inverse="true"</literal>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Mapper une extr�mit� d'une association avec
<literal>inverse="true"</literal> n'affecte
+ pas l'op�ration de cascades, ce sont des concepts orthogonaux !
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-indexedbidirectional">
+ <title>Associations bidirectionnelles avec des collections
index�es</title>
+ <para>
+ Une association bidirectionnelle o� une extr�mit� est repr�sent�e comme une
<literal><list></literal>
+ ou une <literal><map></literal> requiert une
consid�ration sp�ciale. Si il y a une
+ propri�t� de la classe enfant qui mappe la colonne de l'index, pas de
probl�me, nous pouvons
+ continuer � utiliser <literal>inverse="true"</literal>
sur le mapping de la collection :
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children" inverse="true">
+ <key column="parent_id"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <property name="name"
+ not-null="true"/>
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Mais, si il n'y a pas de telle prorpri�t� sur la classe enfant, nous ne
pouvons pas penser
+ � l'association comme vraiment bidirectionnelle (il y a des informations
disponibles � une
+ extr�mit� de l'association qui ne sont pas disponibles � l'autre
extr�mit�). Dans ce cas,
+ nous ne pouvons pas mapper la collection
<literal>inverse="true"</literal>. � la place, nous
+ pourrions utiliser le mapping suivant :
+ </para>
+
+ <programlisting><![CDATA[<class name="Parent">
+ <id name="id" column="parent_id"/>
+ ....
+ <map name="children">
+ <key column="parent_id"
+ not-null="true"/>
+ <map-key column="name"
+ type="string"/>
+ <one-to-many class="Child"/>
+ </map>
+</class>
+
+<class name="Child">
+ <id name="id" column="child_id"/>
+ ....
+ <many-to-one name="parent"
+ class="Parent"
+ column="parent_id"
+ insert="false"
+ update="false"
+ not-null="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Notez que dans ce mapping, l'extr�mit� de l'association contenant la
collection est responsable
+ des mises � jour de la clef �trang�re. � faire : cela entra�ne-t-il r�ellement
des expressions
+ updates inutiles ?
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-ternary">
+ <title>Associations ternaires</title>
+
+ <para>
+ Il y a trois approches possibles pour mapper une association ternaire.
L'une est d'utiliser
+ une <literal>Map</literal> avec une association en tant
qu'index :
+ </para>
+
+ <programlisting><![CDATA[<map name="contracts">
+ <key column="employer_id" not-null="true"/>
+ <map-key-many-to-many column="employee_id"
class="Employee"/>
+ <one-to-many class="Contract"/>
+</map>]]></programlisting>
+
+ <programlisting><![CDATA[<map name="connections">
+ <key column="incoming_node_id"/>
+ <map-key-many-to-many column="outgoing_node_id"
class="Node"/>
+ <many-to-many column="connection_id" class="Connection"/>
+</map>]]></programlisting>
+
+ <para>
+ Une seconde approche est simplement de remodeler l'association comme une
classe d'entit�. C'est
+ l'approche la plus commune.
+ </para>
+
+ <para>
+ Une alternative finale est d'utiliser des �l�ments composites, dont nous
discuterons plus tard.
+ </para>
+
+ </sect2>
+
+ <sect2 id="collections-idbag" revision="1">
+ <title>Utiliser un
<literal><idbag></literal></title>
+
+ <para>
+ Si vous embrassez pleinement notre vue que les clefs compos�es sont une
mauvaise
+ chose et que des entit�s devraient avoir des identifiants artificiels (des
clefs
+ subrog�es), alors vous pourriez trouver un peu curieux que les associations
+ plusieurs-vers-plusieurs et les collections de valeurs que nous avons montr�
jusqu'ici
+ mappent toutes des tables avec des clefs compos�es ! Maintenant, ce point est
assez
+ discutable ; une table d'association pure ne semble pas beaucoup
b�n�ficier d'une clef
+ subrog�e (bien qu'une collection de valeur compos�es le
<emphasis>pourrait</emphasis>).
+ N�anmoins, Hibernate fournit une foncionnalit� qui vous permet de mapper
+ des associations plusieurs-vers-plusieurs et des collections de valeurs vers
une
+ table avec une clef subrog�e.
+ </para>
+
+ <para>
+ L'�l�ment <literal><idbag></literal> vous
laisse mapper une <literal>List</literal>
+ (ou une <literal>Collection</literal>) avec une s�mantique de
sac.
+ </para>
+
+<programlisting><![CDATA[<idbag name="lovers"
table="LOVERS">
+ <collection-id column="ID" type="long">
+ <generator class="sequence"/>
+ </collection-id>
+ <key column="PERSON1"/>
+ <many-to-many column="PERSON2" class="Person"
fetch="join"/>
+</idbag>]]></programlisting>
+
+ <para>
+ Comme vous pouvez voir, un
<literal><idbag></literal> a un g�n�r�teur d'id
+ artificiel, comme une classe d'entit� ! Une clef subrog�e diff�rente est
assign�e
+ � chaque ligne de la collection. Cependant, Hibernate ne fournit pas de
m�canisme pour
+ d�couvrir la valeur d'une clef subrog�e d'une ligne particuli�re.
+ </para>
+
+ <para>
+ Notez que les performances de la mise � jour d'un
<literal><idbag></literal>
+ sont <emphasis>bien</emphasis> meilleures qu'un
<literal><bag></literal> ordinaire !
+ Hibernate peut localiser des lignes individuelles efficacement et les mettre
� jour ou
+ les effacer individuellement, comme une liste, une map ou un ensemble.
+ </para>
+
+ <para>
+ Dans l'impl�mentation actuelle, la strat�gie de la g�n�ration de
l'identifiant <literal>native</literal>
+ n'est pas support�e pour les identifiants de collection
<literal><idbag></literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <!--undocumenting this stuff -->
+
+ <!--sect1 id="collections-heterogeneous">
+ <title>Heterogeneous Associations</title>
+
+ <para>
+ The <literal><many-to-any></literal> and
<literal><index-many-to-any></literal>
+ elements provide for true heterogeneous associations. These mapping elements
work in the
+ same way as the <literal><any></literal> element -
and should also be used
+ rarely, if ever.
+ </para>
+
+ </sect1-->
+
+ <sect1 id="collections-example" revision="1">
+ <title>Exemples de collections</title>
+
+ <para>
+ Les sections pr�c�dentes sont assez confuses. Donc prenons un exemple. Cette
classe :
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+
+public class Parent {
+ private long id;
+ private Set children;
+
+ public long getId() { return id; }
+ private void setId(long id) { this.id=id; }
+
+ private Set getChildren() { return children; }
+ private void setChildren(Set children) { this.children=children; }
+
+ ....
+ ....
+}]]></programlisting>
+
+ <para>
+ a une collection d'instances de <literal>Child</literal>. Si
chaque enfant
+ a au plus un parent, le mapping le plus naturel est une association
+ un-vers-plusieurs :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Ceci mappe les d�finitions de tables suivantes :
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null
primary key )
+create table child ( id bigint not null primary key, name varchar(255), parent_id bigint
)
+alter table child add constraint childfk0 (parent_id) references
parent]]></programlisting>
+
+ <para>
+ Si le parent est <emphasis>requis</emphasis>, utilisez une
association un-vers-plusieurs unidirectionnelle :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ <many-to-one name="parent" class="Parent"
column="parent_id" not-null="true"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Notez la contrainte <literal>NOT NULL</literal> :
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null
primary key )
+create table child ( id bigint not null
+ primary key,
+ name varchar(255),
+ parent_id bigint not null )
+alter table child add constraint childfk0 (parent_id) references
parent]]></programlisting>
+
+ <para>
+ Alternativement, si vous insistez absolument pour que cette association soit
unidirectionnelle,
+ vous pouvez d�clarer la contrainte <literal>NOT NULL</literal>
sur le mapping <literal><key></literal> :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ D'un autre c�t�, si un enfant pouvait avoir plusieurs parent, une
association
+ plusieurs-vers-plusieurs est plus appropri�e :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Parent">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <set name="children" table="childset">
+ <key column="parent_id"/>
+ <many-to-many class="Child" column="child_id"/>
+ </set>
+ </class>
+
+ <class name="Child">
+ <id name="id">
+ <generator class="sequence"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ D�finitions des tables :
+ </para>
+
+ <programlisting><![CDATA[create table parent ( id bigint not null
primary key )
+create table child ( id bigint not null primary key, name varchar(255) )
+create table childset ( parent_id bigint not null,
+ child_id bigint not null,
+ primary key ( parent_id, child_id ) )
+alter table childset add constraint childsetfk0 (parent_id) references parent
+alter table childset add constraint childsetfk1 (child_id) references
child]]></programlisting>
+
+ <para>
+ Pour plus d'exemples et une revue compl�te du mapping de la relation
parent/enfant, voir
+ see <xref linkend="example-parentchild"/>.
+ </para>
+
+ <para>
+ Des mappings d'association plus exotiques sont possibles, nous
cataloguerons toutes les possibilit�s
+ dans le prochain chapitre.
+ </para>
+
+ </sect1>
+
+</chapter>
Copied:
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/component_mapping.xml (from
rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/component_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/component_mapping.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/component_mapping.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,402 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<chapter id="components">
+ <title>Mapping de composants</title>
+
+ <para>
+ La notion de <emphasis>composants</emphasis> est r�utilis� dans
diff�rents contextes,
+ avec diff�rents objectifs, � travers Hibernate.
+ </para>
+
+ <sect1 id="components-dependentobjects" revision="2" >
+ <title>Objects d�pendants</title>
+
+ <para>
+ Le composant est un objet inclu dans un autre qui est sauvegard� comme une
valeur, et
+ non pas comme une entit�.
+ Le composant fait r�f�rence � la notion (au sens objet) de composition
+ (et non pas de composant au sens d'architecture de composants).
+ Par exemple on pourrait mod�lis� l'objet personne de cette fa�on:
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+ private java.util.Date birthday;
+ private Name name;
+ private String key;
+ public String getKey() {
+ return key;
+ }
+ private void setKey(String key) {
+ this.key=key;
+ }
+ public java.util.Date getBirthday() {
+ return birthday;
+ }
+ public void setBirthday(java.util.Date birthday) {
+ this.birthday = birthday;
+ }
+ public Name getName() {
+ return name;
+ }
+ public void setName(Name name) {
+ this.name = name;
+ }
+ ......
+ ......
+}]]></programlisting>
+
+<programlisting><![CDATA[public class Name {
+ char initial;
+ String first;
+ String last;
+ public String getFirst() {
+ return first;
+ }
+ void setFirst(String first) {
+ this.first = first;
+ }
+ public String getLast() {
+ return last;
+ }
+ void setLast(String last) {
+ this.last = last;
+ }
+ public char getInitial() {
+ return initial;
+ }
+ void setInitial(char initial) {
+ this.initial = initial;
+ }
+}]]></programlisting>
+
+ <para>
+ Maintenant <literal>Name</literal> peut-�tre sauvegard� comme un
composant de
+ <literal>Person</literal>. Remarquer que
<literal>Name</literal> d�finit des methodes
+ d'acc�s et de modification pour ses propri�t�s persistantes, mais il
n'a pas besoin
+ des interfaces ou des propri�t�s d'identification ( par exemple getId() )
qui sont propres aux entit�s.
+ </para>
+
+ <para>
+ Nous serions alors amen� � mapper ce composant de cette fa�on:
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person"
table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name"> <!-- class
attribute optional -->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ <para>
+ La table person aurai les colonnes <literal>pid</literal>,
+ <literal>birthday</literal>,
+ <literal>initial</literal>,
+ <literal>first</literal> and
+ <literal>last</literal>.
+ </para>
+
+ <para>
+ Comme tous les types valeurs, les composants ne supportent pas les r�f�rences
partag�s.
+ En d'autres mots, deux instances de person peuvent avoir un m�me nom,
mais ces noms sont
+ ind�pendants, ils peuvent �tre identiques si on les compare par valeur mais ils
repr�sentent
+ deux objets distincts en m�moire. La notion de nullit� pour un composant est
+ <emphasis>ad hoc</emphasis>. Quand il recharge l'objet qui
contient le composant, Hibernate
+ supposera que si tous les champs du composants sont nuls alors le composant
sera positionn�
+ � la valeur null. Ce choix programmatif devrait �tre satisfaisant dans la
plupart des cas.
+ </para>
+
+ <para>
+ Les propri�t�s d'un composant peuvent �tre de tous les types
qu'Hibernate supporte habituellement
+ (collections, many-to-one associations, autres composants, etc). Les
composants inclus ne doivent <emphasis>pas</emphasis>
+ �tre vus comme quelque chose d'exotique. Hibernate a �t� con�u pour
supporter un mod�le objet tr�s granulaire.
+ </para>
+
+ <para>
+ Le <literal><component></literal> peut inclure
dans la liste de ses propri�t�s
+ une r�f�rence au <literal><parent></literal>
conteneur.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Person"
table="person">
+ <id name="Key" column="pid" type="string">
+ <generator class="uuid"/>
+ </id>
+ <property name="birthday" type="date"/>
+ <component name="Name" class="eg.Name"
unique="true">
+ <parent name="namedPerson"/> <!-- r�f�rence arri�re � Person
-->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </component>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-incollections" revision="1">
+ <title>Collection d'objets d�pendants</title>
+
+ <para>
+ Les collections d'objets d�pendants sont support�s (exemple: un tableau
de type
+ <literal>Name</literal>). D�clarer la collection de composants en
rempla�ant le tag <literal><element></literal>
+ par le tag <literal><composite-element></literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="someNames"
table="some_names" lazy="true">
+ <key column="id"/>
+ <composite-element class="eg.Name"> <!-- class attribute required
-->
+ <property name="initial"/>
+ <property name="first"/>
+ <property name="last"/>
+ </composite-element>
+</set>]]></programlisting>
+
+ <para>
+ Remarque: Si vous d�finissez un <literal>Set</literal>
d'�l�ment composite,
+ il est tr�s important d'impl�menter la m�thode
<literal>equals()</literal> et
+ <literal>hashCode()</literal> correctement.
+ </para>
+
+ <para>
+ Les �lements composite peuvent aussi contenir des composants mais pas des
collections.
+ Si votre �l�ment composite contient aussi des composants, utilisez
l'�l�ment <literal><nested-composite-element></literal>
+ . Une collections de composants qui ccontiennent eux-m�mes des composants est
un cas tr�s exotique.
+ A ce stade demandez-vous si une association un-�-plusieurs ne serait pas plus
appropri�.
+ Essayez de re remodeler votre �l�ment composite comme une entit� ( Dans ce
cas m�me si le mod�le
+ Java est le m�me la logique de persitence et de relation sont tout de m�me
diff�rentes)
+ </para>
+
+ <para>
+ Remarque, le mapping d'�l�ments composites ne supporte pas la nullit� des
+ propri�t�s lorsqu'on utilise un
<literal><set></literal>. Hibernate
+ lorsqu'il supprime un objet utilise chaque colonne pour identifier un
objet
+ (on ne peut pas utiliser des cl�s primaires distinctes dans une table
d'�l�ments composites),
+ ce qui n'est pas possible avec des valeurs nulles. Vous devez donc
choisir d'interdire la nullit�
+ des propri�t�s d'un �l�ment composite ou choisir un autre type de
collection comme :
+ <literal><list></literal>,
<literal><map></literal>,
+ <literal><bag></literal> ou
<literal><idbag></literal>.
+ </para>
+
+ <para>
+ Un cas particulier d'�l�ment composite est un �l�ment composite qui
inclut un �l�ment
+ <literal><many-to-one></literal>. Un mapping comme
celui-ci
+ vous permet d'associer les colonnes d'une table d'association
plusieurs � plusieurs (many-to-many)
+ � la classse de l'�l�ment composite. L'exemple suivant est une
association plusieurs � plusieurs
+ de <literal>Order</literal> � <literal>Item</literal>
�
+ <literal>purchaseDate</literal>,
<literal>price</literal> et
+ <literal>quantity</literal> sont des propri�t�s de
l'association.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items"
lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.Purchase">
+ <property name="purchaseDate"/>
+ <property name="price"/>
+ <property name="quantity"/>
+ <many-to-one name="item" class="eg.Item"/> <!--
class attribute is optional -->
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Bien s�r, il ne peut pas y avoir de r�f�rence � l'achat (purchase) depuis
l'article (item), pour
+ pouvoir naviguer de fa�on bidirectionnelle dans l'association.
N'oubliez pas que les composants
+ sont de type valeurs et n'autorise pas les r�f�rences partag�es.
+ </para>
+
+ <para>M�me les associations ternaires ou quaternaires sont
possibles:</para>
+
+ <programlisting><![CDATA[<class name="eg.Order" .... >
+ ....
+ <set name="purchasedItems" table="purchase_items"
lazy="true">
+ <key column="order_id">
+ <composite-element class="eg.OrderLine">
+ <many-to-one name="purchaseDetails
class="eg.Purchase"/>
+ <many-to-one name="item" class="eg.Item"/>
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Les �l�ments composites peuvent appara�tre dans les requ�tes en utilisant
+ la m�me syntaxe que associations
+ </para>
+
+ </sect1>
+
+ <sect1 id="components-asmapindex">
+ <title>Utiliser les composants comme index de map</title>
+
+ <para>
+ l'�l�ment
<literal><composite-map-key></literal>
+ vous permet d'utiliser une classe de composant comme indice de
+ <literal>Map</literal>. Assurez-vous d'avoir surd�fini
+ <literal>hashCode()</literal> et
<literal>equals()</literal> dans la
+ classe du composant.
+ </para>
+ </sect1>
+
+ <sect1 id="components-compositeid" revision="1">
+ <title>Utiliser un composant comme identifiant</title>
+
+ <para>
+ Vous pouvez utiliser un composant comme identifiant d'une entit�.
+ Mais pour cela la classe du composant doit respecter certaines r�gles.
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Elle doit impl�menter
<literal>java.io.Serializable</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Elle doit red�finir <literal>equals()</literal> et
+ <literal>hashCode()</literal>, de fa�on coh�rente avec le
+ fait qu'elle d�finit une cl� composite dans la base de
+ donn�es.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <emphasis>
+ Remarque: avec hibernate3, la seconde r�gle n'est plus absolument
+ necessaire mais fa�tes le quand m�me.</emphasis>
+ </para>
+
+ <para>
+ Vous ne pouvez pas utiliser de
<literal>IdentifierGenerator</literal> pour g�n�rer
+ une cl� composite, l'application devra d�finir elle m�me ses propres
identifiants.
+ </para>
+
+ <para>
+ Utiliser l'�l�ment
<literal><composite-id></literal> (en incluant l'�l�ment
+ <literal><key-property></literal>) � la place de
l'habituel d�claration
+ <literal><id></literal>. Par exemple la classe
+ <literal>OrderLine</literal> qui d�pend de la cl� primaire
+ (composite) de <literal>Order</literal>.
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+
+ <composite-id name="id" class="OrderLineId">
+ <key-property name="lineId"/>
+ <key-property name="orderId"/>
+ <key-property name="customerId"/>
+ </composite-id>
+
+ <property name="name"/>
+
+ <many-to-one name="order" class="Order"
+ insert="false" update="false">
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-one>
+ ....
+
+</class>]]></programlisting>
+
+ <para>
+ Maintenant toutes cl�s �trang�res r�f�ren�ant la table
<literal>OrderLine</literal>
+ devra aussi �tre composite. Vous devez en tenir compte lorsque vous �crivez
vos mapping d'association pour les autres classes.
+ Une association � <literal>OrderLine</literal> devrait �tre mapp�
de la fa�on suivante :
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="orderLine"
class="OrderLine">
+<!-- the "class" attribute is optional, as usual -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+</many-to-one>]]></programlisting>
+
+ <para>
+ (Remarque: l'�l�ment
<literal><column></literal> est une alternative � l'attribut
+ <literal>column</literal> que l'on utilise partout.)
+ </para>
+
+ <para>
+ Une association <literal>plusieurs-�-plusieurs</literal>
(many-to-many) � <literal>OrderLine</literal>
+ utilisera aussi une cl� �trang�re composite:
+ </para>
+
+ <programlisting><![CDATA[<set name="undeliveredOrderLines">
+ <key column name="warehouseId"/>
+ <many-to-many class="OrderLine">
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </many-to-many>
+</set>]]></programlisting>
+
+ <para>
+ La collection des <literal>OrderLine</literal>s dans
<literal>Order</literal>
+ utilisera:
+ </para>
+
+ <programlisting><![CDATA[<set name="orderLines"
inverse="true">
+ <key>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <one-to-many class="OrderLine"/>
+</set>]]></programlisting>
+
+ <para>
+ (L'�l�ment <literal><one-to-many></literal>,
comme d'habitude, ne d�clare pas de colonne.)
+ </para>
+
+ <para>
+ Si <literal>OrderLine</literal> lui-m�me poss�de une collection,
celle-ci aura aussi
+ une cl� composite �trang�re.
+ </para>
+
+ <programlisting><![CDATA[<class name="OrderLine">
+ ....
+ ....
+ <list name="deliveryAttempts">
+ <key> <!-- a collection inherits the composite key type -->
+ <column name="lineId"/>
+ <column name="orderId"/>
+ <column name="customerId"/>
+ </key>
+ <list-index column="attemptId" base="1"/>
+ <composite-element class="DeliveryAttempt">
+ ...
+ </composite-element>
+ </set>
+</class>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="components-dynamic" revision="1">
+ <title>Composant Dynamique</title>
+
+ <para>
+ Vous pouvez m�me mapper une propri�t� de type
<literal>Map</literal>:
+ </para>
+
+ <programlisting><![CDATA[<dynamic-component
name="userAttributes">
+ <property name="foo" column="FOO"/>
+ <property name="bar" column="BAR"/>
+ <many-to-one name="baz" class="Baz"
column="BAZ_ID"/>
+</dynamic-component>]]></programlisting>
+
+ <para>
+ La s�mantique de l'association � un
<literal><dynamic-component></literal>
+ est identique � celle que l'on utilise pour les composants.
+ L'avantage de ce type de mapping est qu'il pemet de d�terminer les
v�ritables propri�t�s
+ du bean au moment su d�ploiement en �ditant simplement le document de
mapping.
+ La manipulation du document de mapping pendant l'execution de
l'application est aussi
+ possible en utilisant un parser DOM. Il ya m�me mieux, vous pouvez acc�der
(et changer)
+ le metamodel de configuration d'hibernate en utilisant l'objet
<literal>Configuration</literal>
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/configuration.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/configuration.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/configuration.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/configuration.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,1759 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<chapter id="session-configuration" revision="1">
+
+ <title>Configuration</title>
+
+ <para>
+ Parce qu'Hibernate est con�u pour fonctionner dans diff�rents
environnements,
+ il existe beaucoup de param�tres de configuration. Heureusement, la plupart
+ ont des valeurs par d�faut appropri�es et la distribution d'Hibernate
contient
+ un exemple de fichier <literal>hibernate.properties</literal> dans le
r�pertoire
+ <literal>etc/</literal> qui montre les diff�rentes options. Vous
n'avez qu'�
+ placer ce fichier dans votre classpath et � l'adapter.
+ </para>
+
+ <sect1 id="configuration-programmatic" revision="1">
+ <title>Configuration par programmation</title>
+
+ <para>
+ Une instance de
<literal>org.hibernate.cfg.Configuration</literal>
+ repr�sente un ensemble de mappings des classes Java d'une application
vers
+ la base de donn�es SQL. La <literal>Configuration</literal> est
utilis�e
+ pour construire un objet (immuable)
<literal>SessionFactory</literal>.
+ Les mappings sont constitu�s d'un ensemble de fichiers de mapping XML.
+ </para>
+
+ <para>
+ Vous pouvez obtenir une instance de
<literal>Configuration</literal>
+ en l'instanciant directement et en sp�cifiant la liste des documents
+ XML de mapping. Si les fichiers de mapping sont dans le classpath, vous
+ pouvez le faire � l'aide de la m�thode
<literal>addResource()</literal> :
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addResource("Item.hbm.xml")
+ .addResource("Bid.hbm.xml");]]></programlisting>
+
+ <para>
+ Une alternative (parfois meilleure) est de sp�cifier les classes mapp�es
+ et de laisser Hibernate trouver les documents de mapping pour vous :
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class);]]></programlisting>
+
+ <para>
+ Hibernate va rechercher les fichiers de mappings
+ <literal>/org/hibernate/auction/Item.hbm.xml</literal> et
+ <literal>/org/hibernate/auction/Bid.hbm.xml</literal> dans le
classpath.
+ Cette approche �limine les noms de fichiers en dur.
+ </para>
+
+ <para>
+ Une <literal>Configuration</literal> vous permet �galement de
pr�ciser des
+ propri�t�s de configuration :
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration()
+ .addClass(org.hibernate.auction.Item.class)
+ .addClass(org.hibernate.auction.Bid.class)
+ .setProperty("hibernate.dialect",
"org.hibernate.dialect.MySQLInnoDBDialect")
+ .setProperty("hibernate.connection.datasource",
"java:comp/env/jdbc/test")
+ .setProperty("hibernate.order_updates",
"true");]]></programlisting>
+
+ <para>
+ Ce n'est pas le seul moyen de passer des propri�t�s de configuration �
Hibernate.
+ Les diff�rentes options sont :
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Passer une instance de
<literal>java.util.Properties</literal>
+ � <literal>Configuration.setProperties()</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Placer <literal>hibernate.properties</literal> dans un
r�pertoire racine
+ du classpath
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Positionner les propri�t�s <literal>System</literal> en
utilisant
+ <literal>java -Dproperty=value</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Inclure des �l�ments
<literal><property></literal> dans le
+ fichier <literal>hibernate.cfg.xml</literal> (voir plus
loin).
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ L'utilisation d'<literal>hibernate.properties</literal>
est l'approche la plus
+ simple si vous voulez d�marrer rapidement
+ </para>
+ <para>
+ La <literal>Configuration</literal> est un objet de d�marrage qui
sera supprim�
+ une fois qu'une <literal>SessionFactory</literal> aura �t�
cr��e.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-sessionfactory">
+ <title>Obtenir une SessionFactory</title>
+
+ <para>
+ Une fois que tous les mappings ont �t� pars�s par la
<literal>Configuration</literal>,
+ l'application doit obtenir une fabrique d'instances de
<literal>Session</literal>.
+ Cette fabrique sera partag�e entre tous les threads de l'application :
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sessions =
cfg.buildSessionFactory();]]></programlisting>
+
+ <para>
+ Hibernate permet � votre application d'instancier plus d'une
<literal>SessionFactory</literal>.
+ Cela est pratique lorsque vous utilisez plus d'une base de donn�es.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-hibernatejdbc" revision="1">
+ <title>Connexions JDBC</title>
+
+ <para>
+ Habituellement, vous voulez que la
<literal>SessionFactory</literal> cr�e les connexions JDBC et
+ les mette dans un pool pour vous. Si vous suivez cette approche, ouvrir une
<literal>Session</literal>
+ est aussi simple que :
+ </para>
+
+ <programlisting><![CDATA[Session session = sessions.openSession(); //
open a new Session]]></programlisting>
+
+ <para>
+ D�s que vous ferez quelquechose qui requiert un acc�s � la base de donn�es,
une connexion
+ JDBC sera r�cup�r�e dans le pool.
+ </para>
+
+ <para>
+ Pour faire cela, il faut passer les propri�t�s de la connexion JDBC �
Hibernate.
+ Tous les noms des propri�t�s Hibernate et leur signification sont d�finies
dans
+ la classe <literal>org.hibernate.cfg.Environment</literal>. Nous
allons maintenant
+ d�crire les param�tres de configuration des connexions JDBC les plus
importants.
+ </para>
+
+ <para>
+ Hibernate obtiendra des connexions (et les mettra dans un pool) en utilisant
+ <literal>java.sql.DriverManager</literal> si vous positionnez les
param�tres de la mani�re
+ suivante :
+ </para>
+
+ <table frame="topbot">
+ <title>Propri�t�s JDBC d'Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nom de la propri�t�</entry>
+ <entry>Fonction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.driver_class</literal>
+ </entry>
+ <entry>
+ <emphasis>Classe du driver jdbc</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.url</literal>
+ </entry>
+ <entry>
+ <emphasis>URL jdbc</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>utilisateur de la base de donn�es</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>mot de passe de la base de donn�es</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.pool_size</literal>
+ </entry>
+ <entry>
+ <emphasis>nombre maximum de connexions dans le
pool</emphasis>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ L'algorithme natif de pool de connexions d'Hibernate est plut�t
rudimentaire. Il a �t� fait
+ dans le but de vous aider � d�marrer et <emphasis>n'est pas pr�vu
pour un syst�me en production</emphasis>
+ ou m�me pour un test de peformance. Utilisez plut�t un pool tiers pour de
meilleures performances et une
+ meilleure stabilit� : pour cela, remplacez la propri�t�
<literal>hibernate.connection.pool_size</literal> avec les propri�t�s
+ sp�cifique au pool de connexions que vous avez choisi. Cela d�sactivera le
pool de connexions interne
+ d'Hibernate. Vous pouvez par exemple utiliser C3P0.
+ </para>
+
+ <para>
+ C3P0 est un pool de connexions JDBC open source distribu� avec Hibernate dans
le r�pertoire
+ <literal>lib</literal>. Hibernate utilisera son provider
<literal>C3P0ConnectionProvider</literal>
+ pour le pool de connexions si vous positionnez les propri�t�s
<literal>hibernate.c3p0.*</literal>.
+ Si vous voulez utiliser Proxool, r�f�rez vous au groupe de propri�t�s
d'<literal>hibernate.properties</literal>
+ correspondant et regardez sur le site web d'Hibernate pour plus
d'informations.
+ </para>
+
+ <para>
+ Voici un exemple de fichier
<literal>hibernate.properties</literal> pour C3P0:
+ </para>
+
+ <programlisting id="c3p0-configuration"
revision="1"><![CDATA[hibernate.connection.driver_class =
org.postgresql.Driver
+hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
+hibernate.connection.username = myuser
+hibernate.connection.password = secret
+hibernate.c3p0.min_size=5
+hibernate.c3p0.max_size=20
+hibernate.c3p0.timeout=1800
+hibernate.c3p0.max_statement=50
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ Dans le cadre de l'utilisation au sein d'un serveur
d'applications,
+ vous devriez quasiment toujours configurer Hibernate pour qu'il obtienne
+ ses connexions de la <literal>DataSource</literal> du serveur
d'application
+ enregistr�e dans le JNDI. Pour cela vous devrez d�finir au moins une des
+ propri�t�s suivantes :
+ </para>
+
+ <table frame="topbot">
+ <title>Propri�t� d'une Datasource Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nom d'une propri�t�</entry>
+ <entry>fonction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.connection.datasource</literal>
+ </entry>
+ <entry>
+ <emphasis>Nom JNDI de la datasource</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.url</literal>
+ </entry>
+ <entry>
+ <emphasis>URL du fournisseur JNDI</emphasis>
(optionnelle)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jndi.class</literal>
+ </entry>
+ <entry>
+ <emphasis>Classe de
l'<literal>InitialContextFactory</literal> du JNDI</emphasis>
(optionnelle)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.username</literal>
+ </entry>
+ <entry>
+ <emphasis>utilisateur de la base de donn�es</emphasis>
(optionnelle)
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.password</literal>
+ </entry>
+ <entry>
+ <emphasis>mot de passe de la base de donn�es</emphasis>
(optionnelle)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Voici un exemple de fichier
<literal>hibernate.properties</literal>
+ pour l'utilisation d'une datasource JNDI fournie par un serveur
d'applications :
+ </para>
+
+ <programlisting><![CDATA[hibernate.connection.datasource =
java:/comp/env/jdbc/test
+hibernate.transaction.factory_class = \
+ org.hibernate.transaction.JTATransactionFactory
+hibernate.transaction.manager_lookup_class = \
+ org.hibernate.transaction.JBossTransactionManagerLookup
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+ <para>
+ Les connexions JDBC obtenues � partir d'une datasource JNDI participeront
automatiquement
+ aux transactions g�r�es par le conteneur du serveur d'applications.
+ </para>
+
+ <para>
+ Des propri�t�s suppl�mentaires de connexion peuvent �tre pass�es en
pr�fixant
+ le nom de la propri�t� par
"<literal>hibernate.connnection</literal>". Par exemple,
+ vous pouvez sp�cifier un jeu de caract�res en utilisant
+ <literal>hibernate.connection.charSet</literal>.
+ </para>
+
+ <para>
+ Vous pouvez fournir votre propre strat�gie d'obtention des connexions
JDBC en impl�mentant l'interface
+ <literal>org.hibernate.connection.ConnectionProvider</literal>.
Vous pouvez s�lectionner
+ une impl�mentation sp�cifique en positionnant
<literal>hibernate.connection.provider_class</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-optional" revision="1">
+ <title>Propri�t�s de configuration optionnelles</title>
+
+ <para>
+ Il y a un certain nombre d'autres propri�t�s qui contr�lent le
fonctionnement
+ d'Hibernate � l'ex�cution. Toutes sont optionnelles et ont comme
valeurs par d�faut
+ des valeurs "raisonnables" pour un fonctionnement nominal.
+ </para>
+
+ <para>
+ <emphasis>Attention : Certaines de ces propri�t�s sont uniquement de
niveau System.</emphasis>
+ Les propri�t�s de niveau System ne peuvent �tre positionn�es que via la ligne
de commande
+ (<literal>java -Dproperty=value</literal>) ou �tre d�finies dans
<literal>hibernate.properties</literal>.
+ Elle <emphasis>ne peuvent pas</emphasis> l'�tre via une des
autres techniques d�crites ci-dessus.
+ </para>
+
+ <table frame="topbot"
id="configuration-optional-properties" revision="8">
+ <title>Propri�t�s de configuration d'Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nom de la propri�t�</entry>
+ <entry>Fonction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.dialect</literal>
+ </entry>
+ <entry>
+ Le nom de la classe du <literal>Dialect</literal>
Hibernate.
+ qui permet � Hibernate de g�n�rer du SQL optimis� pour une
+ base de donn�es relationnelle particuli�re.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+
<literal>nom.complet.de.ma.classe.de.Dialect</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.show_sql</literal>
+ </entry>
+ <entry>
+ Ecrit toutes les requ�tes SQL sur la console. Il s'agit
d'une
+ alternative au positionnement de la cat�gorie de log
+ <literal>org.hibernate.SQL</literal> au niveau
<literal>debug</literal>.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.format_sql</literal>
+ </entry>
+ <entry>
+ Formate et indente le sql dans la console et dans le log
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_schema</literal>
+ </entry>
+ <entry>
+ Positionne dans le SQL g�n�r� un sch�ma/tablespace par d�faut
pour les noms de
+ table ne l'ayant pas surcharg�.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>MON_SCHEMA</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_catalog</literal>
+ </entry>
+ <entry>
+ Qualifie les noms de tables non qualifi�es avec ce catalogue
+ dans le SQL g�n�r�.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>CATALOG_NAME</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.session_factory_name</literal>
+ </entry>
+ <entry>
+ La <literal>SessionFactory</literal> sera
automatiquement
+ li�e � ce nom dans le JNDI apr�s sa cr�ation.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>jndi/nom/hierarchique</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.max_fetch_depth</literal>
+ </entry>
+ <entry>
+ D�finit la profondeur maximale d'un arbre de chargement
par
+ jointures ouvertes pour les associations � cardinalit�
unitaire
+ (un-�-un, plusieurs-�-un).
+ Un <literal>0</literal> d�sactive le chargement
par jointure
+ ouverte.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ valeurs recommand�es entre
<literal>0</literal> et <literal>3</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.default_batch_fetch_size</literal>
+ </entry>
+ <entry>
+ D�finit une taille par d�faut pour le chargement par lot des
associations
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ Valeurs recommand�es : <literal>4</literal>,
<literal>8</literal>,
+ <literal>16</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.default_entity_mode</literal>
+ </entry>
+ <entry>
+ D�finit un mode de repr�sentation par d�faut des entit�s
pour
+ toutes les sessions ouvertes depuis cette
<literal>SessionFactory</literal>
+ <para>
+ <literal>dynamic-map</literal>,
<literal>dom4j</literal>,
+ <literal>pojo</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.order_updates</literal>
+ </entry>
+ <entry>
+ Force Hibernate � trier les updates SQL par la valeur de la
cl�
+ primaire des �l�ments qui sont mis � jour. Cela permet de
limiter
+ les deadlocks de transaction dans les syst�mes hautement
concurents.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.generate_statistics</literal>
+ </entry>
+ <entry>
+ Si activ�, Hibernate va collecter des statistiques utiles
+ pour le r�glage des performances.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.use_identifer_rollback</literal>
+ </entry>
+ <entry>
+ Si activ�, les propri�t�s correspondant � l'identifiant
+ des objets vont �tre remises aux valeurs par d�faut lorsque
+ les objets seront supprim�s.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.use_sql_comments</literal>
+ </entry>
+ <entry>
+ Si activ�, Hibernate va g�n�rer des commentaires �
l'int�rieur
+ des requ�tes SQL pour faciliter le debogage., par d�faut �
<literal>false</literal>.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-jdbc-properties"
revision="8">
+ <title>Propri�t�s Hibernate li�es � JDBC et aux
connexions</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nom de la propri�t�</entry>
+ <entry>Fonction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.fetch_size</literal>
+ </entry>
+ <entry>
+ Une valeur non nulle d�termine la taille de chargement
+ des statements JDBC (appelle
+ <literal>Statement.setFetchSize()</literal>).
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.batch_size</literal>
+ </entry>
+ <entry>
+ Une valeur non nulle active l'utilisation par Hibernate
des mises
+ � jour par batch de JDBC2.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ les valeurs recommand�es entre
<literal>5</literal> et <literal>30</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.jdbc.batch_versioned_data</literal>
+ </entry>
+ <entry>
+ Param�trez cette propri�t� �
<literal>true</literal> si votre pilote JDBC
+ retourne des row counts corrects depuis
<literal>executeBatch()</literal> (il est
+ souvent appropri� d'activer cette option). Hibernate
utilisera alors le "batched DML" pour
+ versionner automatiquement les donn�es. Par d�faut =
<literal>false</literal>.
+ <para>
+ <emphasis
role="strong">eg.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.jdbc.factory_class</literal>
+ </entry>
+ <entry>
+ S�lectionne un <literal>Batcher</literal>
personnalis�. La
+ plupart des applications n'auront pas besoin de cette
propri�t�
+ de configuration
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+
<literal>classname.of.BatcherFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.jdbc.use_scrollable_resultset</literal>
+ </entry>
+ <entry>
+ Active l'utilisation par Hibernate des resultsets
scrollables
+ de JDBC2. Cette propri�t� est seulement n�cessaire lorsque
l'on
+ utilise une connexion JDBC fournie par l'utilisateur.
Autrement,
+ Hibernate utilise les m�tadonn�es de la connexion.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.jdbc.use_streams_for_binary</literal>
+ </entry>
+ <entry>
+ Utilise des flux lorsque l'on �crit/lit des types
+ <literal>binary</literal> ou
<literal>serializable</literal>
+ vers et � partir de JDBC (propri�t� de niveau syst�me).
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.jdbc.use_get_generated_keys</literal>
+ </entry>
+ <entry>
+ Active l'utilisation de
<literal>PreparedStatement.getGeneratedKeys()</literal> de JDBC3
+ pour r�cup�rer nativement les cl�s g�n�r�es apr�s insertion.
N�cessite un pilote
+ JDBC3+, le mettre � false si votre pilote a des probl�mes
avec les g�n�rateurs
+ d'identifiant Hibernate. Par d�faut, essaie de d�terminer
les possibilit�s du
+ pilote en utilisant les meta donn�es de connexion.
+ <para>
+ <emphasis
role="strong">eg.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.connection.provider_class</literal>
+ </entry>
+ <entry>
+ Le nom de la classe d'un
<literal>ConnectionProvider</literal> personnalis�
+ qui fournit des connexions JDBC � Hibernate
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+
<literal>classname.of.ConnectionProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.connection.isolation</literal>
+ </entry>
+ <entry>
+ D�finit le niveau d'isolation des transactions JDBC.
Regardez
+ <literal>java.sql.Connection</literal> pour conna�tre
le
+ sens des diff�rentes valeurs mais notez �galement que la plupart
+ des bases de donn�es ne supportent pas tous les niveaux
d'isolation.
+ <para>
+ <emphasis role="strong">ex.</emphasis>
+ <literal>1, 2, 4, 8</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.connection.autocommit</literal>
+ </entry>
+ <entry>
+ Active le mode de commit automatique (autocommit) pour les
connexions
+ JDBC du pool (non recommand�).
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.connection.release_mode</literal>
+ </entry>
+ <entry>
+ Sp�cifie � quel moment Hibernate doit relacher les connexion
JDBC.
+ Par d�faut une connexion JDBC est conserv�e jusqu'� ce
que la session
+ soit explicitement ferm�e ou d�connect�e. Pour une source de
donn�es
+ JTA d'un serveur d'application, vous devriez utiliser
<literal>after_statement</literal>
+ pour lib�rer les connexions de mani�re plus agressive apr�s
chaque appel
+ JDBC. Pour une connexion non JTA, il est souvent pr�f�rable
de lib�rer
+ la connexion � la fin de chaque transaction en utilisant
<literal>after_transaction</literal>.
+ <literal>auto</literal> choisira
<literal>after_statement</literal> pour
+ des transactions JTA et CMT et
<literal>after_transaction</literal> pour
+ des transactions JDBC.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>on_close</literal> (default) |
<literal>after_transaction</literal> |
+ <literal>after_statement</literal> |
<literal>auto</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.connection.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ Passe la propri�t�
JDBC<literal>propertyName</literal>
+ � <literal>DriverManager.getConnection()</literal>.
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.jndi.<emphasis><propertyName></emphasis></literal>
+ </entry>
+ <entry>
+ Passe la propri�t� <literal>propertyName</literal>
� l'<literal>InitialContextFactory</literal>
+ de JNDI.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-cache-properties"
revision="7">
+ <title>Propri�t�s du Cache d'Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nom de la propri�t�</entry>
+ <entry>Fonction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+
<literal>hibernate.cache.provider_class</literal>
+ </entry>
+ <entry>
+ Le nom de classe d'un
<literal>CacheProvider</literal>
+ sp�cifique.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+
<literal>nom.de.classe.du.CacheProvider</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.cache.use_minimal_puts</literal>
+ </entry>
+ <entry>
+ Optimise le cache de second niveau en minimisant les
�critures,
+ au prix de plus de lectures. Ce param�tre est surtout utile
pour
+ les caches en cluster et est activ� par d�faut dans
hibernate3
+ pour les impl�mentations de cache en cluster.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.cache.use_query_cache</literal>
+ </entry>
+ <entry>
+ Activer le cache de requ�te, les requ�tes individuelles
doivent tout
+ de m�me �tre d�clar�es comme pouvant �tre mise en cache.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.cache.use_second_level_cache</literal>
+ </entry>
+ <entry>
+ Peut �tre utilis� pour d�sactiver compl�tement le cache de
second niveau
+ qui est activ� par d�faut pour les classes qui sp�cifient un
�l�ment
+ <literal><cache></literal> dans
leur mapping.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.cache.query_cache_factory</literal>
+ </entry>
+ <entry>
+ Le nom de classe d'une interface
<literal>QueryCacheFactory</literal> ,
+ par d�faut = built-in
<literal>StandardQueryCacheFactory</literal>.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+
<literal>nom.de.la.classe.de.QueryCacheFactory</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>hibernate.cache.region_prefix</literal>
+ </entry>
+ <entry>
+ Un pr�fixe � utiliser pour le nom des r�gions du
+ cache de second niveau.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>prefix</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.cache.use_structured_entries</literal>
+ </entry>
+ <entry>
+ Force Hibernate � stocker les donn�es dans le cache de
+ second niveau dans un format plus adapt� � la visualisation
+ par un humain.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true|false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot"
id="configuration-transaction-properties" revision="9">
+ <title>Propri�t�s des transactions Hibernate</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nom de la propri�t�</entry>
+ <entry>Fonction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+
<literal>hibernate.transaction.factory_class</literal>
+ </entry>
+ <entry>
+ Le nom de classe d'une
<literal>TransactionFactory</literal>
+ qui sera utilis�e par l'API
<literal>Transaction</literal>
+ d'Hibernate (la valeur par d�faut est
+ <literal>JDBCTransactionFactory</literal>).
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+
<literal>nom.de.classe.d.une.TransactionFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>jta.UserTransaction</literal>
+ </entry>
+ <entry>
+ Le nom JNDI utilis� par la
<literal>JTATransactionFactory</literal>
+ pour obtenir la
<literal>UserTransaction</literal> JTA du serveur
+ d'applications.
+ <para>
+ <emphasis
role="strong">eg.</emphasis>
+ <literal>jndi/nom/compose</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.transaction.manager_lookup_class</literal>
+ </entry>
+ <entry>
+ Le nom de la classe du
<literal>TransactionManagerLookup</literal>
+ - requis lorsque le cache de niveau JVM est activ� ou lorsque
l'on
+ utilise un g�n�rateur hilo dans un environnement JTA.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+
<literal>nom.de.classe.du.TransactionManagerLookup</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.transaction.flush_before_completion</literal>
+ </entry>
+ <entry>
+ Si activ�, la session sera automatiquement vid�e durant la
phase
+ qui pr�c�de la fin de la transaction (before completion).
+ La gestion automatique de contexte fourni par Hibernate est
+ recommand�e, voir
+ <xref
linkend="architecture-current-session"/>.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.transaction.auto_close_session</literal>
+ </entry>
+ <entry>
+ Si activ�, la session sera automatiquement ferm� pendant la
phase
+ qui suit la fin de la transaction (after completion).
+ La gestion automatique de contexte fourni par Hibernate est
+ recommand�e, voir
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="topbot" id="configuration-misc-properties"
revision="9">
+ <title>Propri�t�s diverses</title>
+ <tgroup cols="2">
+ <colspec colname="c1" colwidth="1*"/>
+ <colspec colname="c2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Nom de la propri�t�</entry>
+ <entry>Fonction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+
<literal>hibernate.current_session_context_class</literal>
+ </entry>
+ <entry>
+ Fournit une strat�gie particuli�re pour contextualiser
+ la <literal>Session</literal> courante. Voir
+ <xref
linkend="architecture-current-session"/> pour plus
+ d'informations sur les strat�gies fournies.
+ <para>
+ <emphasis
role="strong">eg.</emphasis>
+ <literal>jta</literal> |
<literal>thread</literal> |
+ <literal>custom.Class</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.factory_class</literal>
+ </entry>
+ <entry>
+ Choisi l'impl�mentation du parseur de requ�te
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+
<literal>org.hibernate.hql.ast.ASTQueryTranslatorFactory</literal> ou
+
<literal>org.hibernate.hql.classic.ClassicQueryTranslatorFactory</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.query.substitutions</literal>
+ </entry>
+ <entry>
+ Lien entre les tokens de requ�tes Hibernate et les
+ tokens SQL (les tokens peuvent �tre des fonctions ou des
+ noms litt�raux par exemple).
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>hqlLiteral=SQL_LITERAL,
hqlFunction=SQLFUNC</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <literal>hibernate.hbm2ddl.auto</literal>
+ </entry>
+ <entry>
+ Valide ou exporte automatiquement le sch�ma DDL vers la base
de donn�es
+ lorsque la <literal>SessionFactory</literal> est
cr��e.
+ La valeur <literal>create-drop</literal> permet
de supprimer
+ le sch�ma de base de donn�es lorsque la
<literal>SessionFactory</literal>
+ est ferm�e explicitement.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>validate</literal> |
<literal>update</literal> |
+ <literal>create</literal> |
<literal>create-drop</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+
<literal>hibernate.cglib.use_reflection_optimizer</literal>
+ </entry>
+ <entry>
+ Active l'utilisation de CGLIB � la place de la r�flexion
� l'ex�cution
+ (Propri�t� de niveau syst�me). La r�flexion peut parfois �tre
utile pour
+ r�soudre des probl�mes. Notez qu'Hibernate a tout de m�me
toujours besoin
+ de CGLIB m�me si l'optimiseur est d�sactiv�. Cette
optimisation ne peut �tre
+ d�finie que dans le fichier
<literal>hibernate.cfg.xml</literal>.
+ <para>
+ <emphasis
role="strong">ex.</emphasis>
+ <literal>true</literal> |
<literal>false</literal>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="configuration-optional-dialects"
revision="1">
+ <title>Dialectes SQL</title>
+
+ <para>
+ Vous devriez toujours positionner la propri�t�
<literal>hibernate.dialect</literal> �
+ la sous-classe de
<literal>org.hibernate.dialect.Dialect</literal> appropri�e �
+ votre base de donn�es. Si vous sp�cifiez un dialecte,
+ Hibernate utilisera des valeurs adapt�es pour certaines autres
+ propri�t�s list�es ci-dessus, vous �vitant l'effort de le faire � la
main.
+ </para>
+
+ <table frame="topbot" id="sql-dialects"
revision="2">
+ <title>Dialectes SQL d'Hibernate
(<literal>hibernate.dialect</literal>)</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>SGBD</entry>
+ <entry>Dialecte</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>DB2</entry>
<entry><literal>org.hibernate.dialect.DB2Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 AS/400</entry>
<entry><literal>org.hibernate.dialect.DB2400Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>DB2 OS390</entry>
<entry><literal>org.hibernate.dialect.DB2390Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>PostgreSQL</entry>
<entry><literal>org.hibernate.dialect.PostgreSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL</entry>
<entry><literal>org.hibernate.dialect.MySQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with InnoDB</entry>
<entry><literal>org.hibernate.dialect.MySQLInnoDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>MySQL with MyISAM</entry>
<entry><literal>org.hibernate.dialect.MySQLMyISAMDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle (any version)</entry>
<entry><literal>org.hibernate.dialect.OracleDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Oracle 9i/10g</entry>
<entry><literal>org.hibernate.dialect.Oracle9Dialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase</entry>
<entry><literal>org.hibernate.dialect.SybaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Sybase Anywhere</entry>
<entry><literal>org.hibernate.dialect.SybaseAnywhereDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Microsoft SQL Server</entry>
<entry><literal>org.hibernate.dialect.SQLServerDialect</literal></entry>
+ </row>
+ <row>
+ <entry>SAP DB</entry>
<entry><literal>org.hibernate.dialect.SAPDBDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Informix</entry>
<entry><literal>org.hibernate.dialect.InformixDialect</literal></entry>
+ </row>
+ <row>
+ <entry>HypersonicSQL</entry>
<entry><literal>org.hibernate.dialect.HSQLDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Ingres</entry>
<entry><literal>org.hibernate.dialect.IngresDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Progress</entry>
<entry><literal>org.hibernate.dialect.ProgressDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Mckoi SQL</entry>
<entry><literal>org.hibernate.dialect.MckoiDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Interbase</entry>
<entry><literal>org.hibernate.dialect.InterbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Pointbase</entry>
<entry><literal>org.hibernate.dialect.PointbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>FrontBase</entry>
<entry><literal>org.hibernate.dialect.FrontbaseDialect</literal></entry>
+ </row>
+ <row>
+ <entry>Firebird</entry>
<entry><literal>org.hibernate.dialect.FirebirdDialect</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-outerjoin"
revision="4">
+ <title>Chargement par Jointure Ouverte</title>
+
+ <para>
+ Si votre base de donn�es supporte les outer joins de type ANSI, Oracle ou
Sybase,
+ <emphasis>le chargement par jointure ouverte</emphasis>
devrait am�liorer les
+ performances en limitant le nombre d'aller-retour avec la base de
donn�es (la
+ base de donn�es effectuant donc potentiellement plus de travail). Le
chargement par
+ jointure ouverte permet � un graphe entier d'objets connect�s par une
relation plusieurs-�-un,
+ un-�-plusieurs ou un-�-un d'�tre charg� en un seul
<literal>SELECT</literal> SQL.
+ </para>
+
+ <para>
+ Le chargement par jointure ouverte peut �tre d�sactiver
<emphasis>globalement</emphasis>
+ en mettant la propri�t�
<literal>hibernate.max_fetch_depth</literal> �
<literal>0</literal>.
+ Une valeur de <literal>1</literal> ou plus active le
chargement par jointure ouverte
+ pour les associatiosn un-�-un et plusieurs-�-un qui ont �t� mapp�e avec
+ <literal>fetch="join"</literal>.
+ </para>
+
+ <para>
+ Reportez vous � <xref linkend="performance-fetching"/>
pour plus d'information.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-binarystreams"
revision="1">
+ <title>Flux binaires</title>
+
+ <para>
+ Oracle limite la taille d'un tableau de
<literal>byte</literal> qui peuvent �tre
+ pass�es � et vers son pilote JDBC. Si vous souhaitez utiliser des
instances larges
+ de type <literal>binary</literal> ou
<literal>serializable</literal>, vous devez activer
+ la propri�t�
<literal>hibernate.jdbc.use_streams_for_binary</literal>.
<emphasis>C'est une
+ fonctionalit� de niveau syst�me uniquement.</emphasis>
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-cacheprovider"
revision="2">
+ <title>Cache de second niveau et cache de requ�tes</title>
+
+ <para>
+ Les propri�t�s pr�fix�es par
<literal>hibernate.cache</literal>
+ vous permettent d'utiliser un syst�me de cache de second niveau. Ce
cache
+ peut avoir une port�e dans le processus ou m�me �tre utilisable dans un
+ syst�me distribu�. R�f�rez vous au chapitre <xref
linkend="performance-cache"/>
+ pour plus de d�tails.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-querysubstitution">
+ <title>Substitution dans le langage de requ�tage</title>
+
+ <para>
+ Vous pouvez d�finir de nouveaux tokens dans les requ�tes Hibernate en
utilisant la propri�t�
+ <literal>hibernate.query.substitutions</literal>. Par exemple
:
+ </para>
+
+ <programlisting>hibernate.query.substitutions vrai=1,
faux=0</programlisting>
+
+ <para>
+ remplacerait les tokens <literal>vrai</literal> et
<literal>faux</literal> par
+ des entiers dans le SQL g�n�r�.
+ </para>
+
+ <programlisting>hibernate.query.substitutions
toLowercase=LOWER</programlisting>
+
+ <para>
+ permettrait de renommer la fonction SQL
<literal>LOWER</literal> en <literal>toLowercase</literal>
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-statistics"
revision="2">
+ <title>Statistiques Hibernate</title>
+
+ <para>
+ Si vous activez
<literal>hibernate.generate_statistics</literal>, Hibernate va
+ fournir un certains nombre de m�triques utiles pour r�gler les
performances
+ d'une application qui tourne via
<literal>SessionFactory.getStatistics()</literal>.
+ Hibernate peut aussi �tre configur� pour exposer ces statistiques via
JMX.
+ Lisez les Javadoc des interfaces dans le package
+ <literal>org.hibernate.stats</literal> pour plus
d'informations.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="configuration-logging">
+ <title>Tracer</title>
+
+ <para>
+ Hibernate trace divers �v�nements en utilisant Apache commons-logging.
+ </para>
+
+ <para>
+ Le service commons-logging d�l�guera directement � Apache Log4j
+ (si vous incluez <literal>log4j.jar</literal> dans votre
classpath)
+ ou le syst�me de trace du JDK 1.4 (si vous tournez sous le JDK 1.4
+ et sup�rieur). Vous pouvez t�l�charger Log4j � partir de
+ <literal>http://jakarta.apache.org</literal>. Pour utiliser
Log4j,
+ vous devrez placer dans votre classpath un fichier
+ <literal>log4j.properties</literal>. Un exemple de fichier est
distribu�
+ avec Hibernate dans le r�pertoire <literal>src/</literal>.
+ </para>
+
+ <para>
+ Nous vous recommandons fortement de vous familiariser avec les messages des
traces
+ d'Hibernate. Beaucoup de soins a �t� apport� pour donner le plus de
d�tails
+ possible sans les rendre illisibles. C'est un outil essentiel en cas de
soucis.
+ Les cat�gories de trace les plus int�ressantes sont les suivantes :
+ </para>
+
+ <table frame="topbot" id="log-categories"
revision="2">
+ <title>Cat�gories de trace d'Hibernate</title>
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>Cat�gorie</entry>
+ <entry>Fonction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+
<entry><literal>org.hibernate.SQL</literal></entry>
+ <entry>Trace toutes les requ�ts SQL de type DML
(gestion des donn�es) qui sont ex�cut�es</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.type</literal></entry>
+ <entry>Trace tous les param�tres JDBC</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.tool.hbm2ddl</literal></entry>
+ <entry>Trace toutes les requ�ts SQL de type DDL
(gestion de la structure de la base) qui sont ex�cut�es</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.pretty</literal></entry>
+ <entry>
+ Trace l'�tat de toutes les entit�s (20 entit�s
maximum) qui
+ sont associ�es avec la session hibernate au moment du
flush
+ </entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.cache</literal></entry>
+ <entry>Trace toute l'activit� du cache de second
niveau</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction</literal></entry>
+ <entry>Trace toute l'activit� relative aux
transactions</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.jdbc</literal></entry>
+ <entry>Trace toute acquisition de ressource
JDBC</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.hql.ast.AST</literal></entry>
+ <entry>
+ Trace l'arbre syntaxique des requ�tes HQL et SQL
durant l'analyse syntaxique des requ�tes
+ </entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.secure</literal></entry>
+ <entry>Trace toutes les demandes d'autorisation
JAAS</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate</literal></entry>
+ <entry>
+ Trace tout (beaucoupe d'informations, mais tr�s utile
pour r�soudre les probl�mes).
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Lorsque vous d�veloppez des applications avec Hibernate, vous devriez
quasiment toujours
+ travailler avec le niveau <literal>debug</literal> activ� pour la
cat�gorie
+ <literal>org.hibernate.SQL</literal>, ou sinon avec la propri�t�
+ <literal>hibernate.show_sql</literal> activ�e.
+ </para>
+
+
+ </sect1>
+
+ <sect1 id="configuration-namingstrategy">
+ <title>Impl�menter une
<literal>NamingStrategy</literal></title>
+
+ <para>
+ L'interface
<literal>org.hibernate.cfg.NamingStrategy</literal> vous permet de
+ sp�cifier une "strat�gie de nommage" des objets et �l�ments de la
base de donn�es.
+ </para>
+
+ <para>
+ Vous pouvez fournir des r�gles pour automatiquement g�n�rer les identifiants
+ de base de donn�es � partir des identifiants Java, ou transformer une
colonne
+ ou table "logique" donn�e dans le fichier de mapping en une colonne
ou table
+ "physique". Cette fonctionnalit� aide � r�duire la verbosit� de
documents
+ de mapping, en �liminant le bruit r�p�titif (les pr�fixes
<literal>TBL_</literal>
+ par exemple). La strat�gie par d�faut utilis�e par Hibernate est minimale.
+ </para>
+
+ <para>
+ Vous pouvez d�finir une strat�gie diff�rente en appelant
+ <literal>Configuration.setNamingStrategy()</literal> avant
d'ajouter des
+ mappings :
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new Configuration()
+ .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
+ .addFile("Item.hbm.xml")
+ .addFile("Bid.hbm.xml")
+ .buildSessionFactory();]]></programlisting>
+
+ <para>
+ <literal>net.sf.hibernate.cfg.ImprovedNamingStrategy</literal>
est une
+ strat�gie fournie qui peut �tre utile comme point de d�part de quelques
+ applications.
+ </para>
+
+ </sect1>
+
+ <sect1 id="configuration-xmlconfig" revision="2">
+ <title>Fichier de configuration XML</title>
+
+ <para>
+ Une approche alternative est de sp�cifier toute la configuration dans un
+ fichier nomm� <literal>hibernate.cfg.xml</literal>. Ce fichier
peut �tre
+ utilis� � la place du fichier
<literal>hibernate.properties</literal>, voire
+ m�me peut servir � surcharger les propri�t�s si les deux fichiers sont
pr�sents.
+ </para>
+
+ <para>
+ Le fichier de configuration XML doit par d�faut se placer � la racine
+ du <literal>CLASSPATH</literal>. En voici un exemple :
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0'
encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <!-- a SessionFactory instance listed as /jndi/name -->
+ <session-factory
+ name="java:hibernate/SessionFactory">
+
+ <!-- properties -->
+ <property
name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
+ <property
name="dialect">org.hibernate.dialect.MySQLDialect</property>
+ <property name="show_sql">false</property>
+ <property name="transaction.factory_class">
+ org.hibernate.transaction.JTATransactionFactory
+ </property>
+ <property
name="jta.UserTransaction">java:comp/UserTransaction</property>
+
+ <!-- mapping files -->
+ <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
+ <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
+
+ <!-- cache settings -->
+ <class-cache class="org.hibernate.auction.Item"
usage="read-write"/>
+ <class-cache class="org.hibernate.auction.Bid"
usage="read-only"/>
+ <collection-cache collection="org.hibernate.auction.Item.bids"
usage="read-write"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ Commme vous pouvez le voir, l'avantage de cette approche est
l'externalisation
+ des noms des fichiers de mapping de la configuration. Le fichier
<literal>hibernate.cfg.xml</literal>
+ est �galement plus pratique quand on commence � r�gler le cache
d'Hibernate. Notez
+ que vous pouvez choisir entre utiliser
<literal>hibernate.properties</literal> ou
+ <literal>hibernate.cfg.xml</literal>, les deux sont �quivalents,
sauf en ce qui
+ concerne les b�n�fices de l'utilisation de la syntaxe XML mentionn�s
ci-dessus.
+ </para>
+
+ <para>
+ Avec la configuration XML, d�marrer Hibernate devient donc aussi simple que
ceci :
+ </para>
+
+ <programlisting><![CDATA[SessionFactory sf = new
Configuration().configure().buildSessionFactory();]]></programlisting>
+
+
+
+ </sect1>
+
+ <sect1 id="configuration-j2ee" revision="1">
+ <title>Int�gration � un serveur d'application J2EE</title>
+
+ <para>
+ Hibernate poss�de les points suivants d'int�gration �
l'infrastructure J2EE :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Source de donn�es g�r�e par le conteneur</emphasis>
: Hibernate peut
+ utiliser des connexions JDBC g�r�es par le conteneur et fournie par
l'interm�diaire
+ de JNDI. Souvent, un <literal>TransactionManager</literal>
compatible JTA
+ et un <literal>ResourceManager</literal> s'occupent de la
gestion des transactions (CMT).
+ Ils sont particuli�rement pr�vus pour pouvoir g�rer des transactions
distribu�es
+ sur plusieurs sources de donn�es. Vous pouvez bien s�r �galement d�finir
vos
+ limites de transaction dans votre programme (BMT) ou vous pouvez sinon
aussi
+ utiliser l'API optionnelle <literal>Transaction</literal>
d'Hibernate qui vous garantira
+ la portabilit� de votre code entre plusieurs serveurs d'application.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Association JNDI automatique</emphasis>: Hibernate
peut associer sa
+ <literal>SessionFactory</literal> � JNDI apr�s le d�marrage.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Association de la Session � JTA:</emphasis> La
<literal>Session</literal> Hibernate
+ peut �tre associ�e automatiquement � une transaction JTA si vous utilisez
les EJBs.
+ Vous avez juste � r�cup�rer la
<literal>SessionFactory</literal> depuis JNDI et
+ � r�cup�rer la <literal>Session</literal> courante. Hibernate
s'occupe de vider et
+ fermer la <literal>Session</literal> lorsque le transaction
JTA se termine. La
+ d�marcation des transactions se fait de mani�re d�clarative dans les
descripteurs de d�ploiement.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>D�ploiement JMX :</emphasis>Si vous avez un serveur
d'application compatible JMX
+ (JBoss AS par exemple), vous pouvez choisir de d�ployer Hibernate en
temps que MBean g�r� par
+ le serveur. Cela vous �vite de coder la ligne de d�marrage qui permet de
construire
+ la <literal>SessionFactory</literal> depuis la
<literal>Configuration</literal>.
+ Le conteneur va d�marrer votre
<literal>HibernateService</literal>, et va id�alement
+ s'occuper des d�pendances entre les services (la source de donn�es
doit �tre disponible
+ avant qu'Hibernate ne d�marre, etc).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ En fonction de votre environnement, vous devrez peut �tre mettre l'option
de
+ configuration
<literal>hibernate.connection.aggressive_release</literal> � vrai si
+ le serveur d'application affiche des exceptions de type "connection
containment".
+ </para>
+
+ <sect2 id="configuration-optional-transactionstrategy"
revision="3">
+ <title>Configuration de la strat�gie transactionnelle</title>
+
+ <para>
+ L'API de la <literal>Session</literal> Hibernate est
ind�pendante de tout syst�me
+ de d�marcation des transactions qui peut �tre pr�sent dans votre
architecture. Si
+ vous laissez Hibernate utiliser l'API JDBC directement via un pool de
connexion, vous
+ devrez commencer et terminer vos transactions en utilisant l'API
JDBC. Si votre
+ application tourne � l'int�rieur d'un serveur d'application
J2EE, vous voudrez peut �tre
+ utiliser les transactions g�r�es par les beans (BMT) et appeller
l'API JTA et
+ <literal>UserTransaction</literal> lorsque cela est
n�cessaire.
+ </para>
+ <para>
+ Pour conserver votre code portable entre ces deux environnements (et
d'autres �ventuels)
+ nous vous recommandons d'utiliser l'API optionnelle
<literal>Transaction</literal> d'Hibernate,
+ qui va encapsuler et masquer le syst�me de transaction sous-jacent.
+ Pour cela, vous devez pr�ciser une classe de fabrique d'instances de
<literal>Transaction</literal>
+ en positionnant la propri�t�
+ <literal>hibernate.transaction.factory_class</literal>.
+ </para>
+
+ <para>
+ Il existe trois choix standards (fournis) :
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+
<term><literal>net.sf.hibernate.transaction.JDBCTransactionFactory</literal></term>
+ <listitem>
+ <para>d�l�gue aux transactions de la base de donn�es
(JDBC). Valeur par d�faut.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+
<term><literal>org.hibernate.transaction.JTATransactionFactory</literal></term>
+ <listitem>
+ <para>
+ d�l�gue � CMT si une transaction existante est sous ce
contexte (ex: m�thode
+ d'un EJB session), sinon une nouvelle transaction est
entam�e et
+ une transaction g�r�e par le bean est utilis�e.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+
<term><literal>org.hibernate.transaction.CMTTransactionFactory</literal></term>
+ <listitem>
+ <para>d�l�gue � aux transactions JTA g�r�es par le
conteneur</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Vous pouvez �galement d�finir votre propre strat�gie transactionnelle
+ (pour un service de transaction CORBA par exemple).
+ </para>
+
+ <para>
+ Certaines fonctionnalit�s d'Hibernate (i.e. le cache de second
niveau, l'association
+ automatique des Session � JTA, etc.) n�cessitent l'acc�s au
<literal>TransactionManager</literal>
+ JTA dans un environnement "manag�". Dans un serveur
d'application, vous devez indiquer
+ comment Hibernate peut obtenir une r�f�rence vers le
<literal>TransactionManager</literal>,
+ car J2EE ne fournit pas un seul m�canisme standard.
+ </para>
+
+ <table frame="topbot" id="jtamanagerlookup"
revision="1">
+ <title>TransactionManagers JTA</title>
+ <tgroup cols="2">
+ <colspec colwidth="2.5*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Fabrique de Transaction</entry>
+ <entry align="center">Serveur
d'application</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+
<entry><literal>org.hibernate.transaction.JBossTransactionManagerLookup</literal></entry>
+ <entry align="center">JBoss</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.WeblogicTransactionManagerLookup</literal></entry>
+ <entry align="center">Weblogic</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.WebSphereTransactionManagerLookup</literal></entry>
+ <entry
align="center">WebSphere</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</literal></entry>
+ <entry align="center">WebSphere
6</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.OrionTransactionManagerLookup</literal></entry>
+ <entry align="center">Orion</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.ResinTransactionManagerLookup</literal></entry>
+ <entry align="center">Resin</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.JOTMTransactionManagerLookup</literal></entry>
+ <entry align="center">JOTM</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.JOnASTransactionManagerLookup</literal></entry>
+ <entry align="center">JOnAS</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.JRun4TransactionManagerLookup</literal></entry>
+ <entry align="center">JRun4</entry>
+ </row>
+ <row>
+
<entry><literal>org.hibernate.transaction.BESTransactionManagerLookup</literal></entry>
+ <entry align="center">Borland
ES</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="configuration-optional-jndi" revision="3">
+ <title><literal>SessionFactory</literal> associ�e au
JNDI</title>
+
+ <para>
+ Une <literal>SessionFactory</literal> Hibernate associ�e au
JNDI peut
+ simplifier l'acc�s � la fabrique et donc la cr�ation de nouvelles
+ <literal>Session</literal>s. Notez que cela n'est pas li�
avec les <literal>Datasource</literal>
+ associ�es au JNDI, elles utilisent juste le m�me registre.
+ </para>
+
+ <para>
+ Si vous d�sirez associer la <literal>SessionFactory</literal>
� un nom JNDI,
+ sp�cifiez un nom (ex.
<literal>java:hibernate/SessionFactory</literal>) en
+ utilisant la propri�t�
<literal>hibernate.session_factory_name</literal>.
+ Si cette propri�t� est omise, la
<literal>SessionFactory</literal> ne sera pas
+ associ�e au JNDI (c'est particuli�rement pratique dans les
environnements ayant une
+ impl�mentation de JNDI en lecture seule, comme c'est le cas pour
Tomcat).
+ </para>
+
+ <para>
+ Lorsqu'il associe la <literal>SessionFactory</literal> au
JNDI, Hibernate utilisera
+ les valeurs de <literal>hibernate.jndi.url</literal>,
<literal>hibernate.jndi.class</literal>
+ pour instancier un contexte d'initialisation. S'ils ne sont pas
sp�cifi�s,
+ l'<literal>InitialContext</literal> par d�faut sera
utilis�.
+ </para>
+
+ <para>
+ Hibernate va automatiquement placer la
<literal>SessionFactory</literal> dans JNDI
+ apr�s avoir appel�
<literal>cfg.buildSessionFactory()</literal>. Cela signifie que vous
+ devez avoir cet appel dans un code de d�marrage (ou dans une classe
utilitaire) dans
+ votre application sauf si vous utilisez le d�ploiement JMX avec le
service
+ <literal>HibernateService</literal> pr�sent� plus tard dans
ce document.
+ </para>
+ <para>
+ Si vous utilisez <literal>SessionFactory</literal> JNDI, un
EJB ou n'importe quelle autre classe
+ peut obtenir la <literal>SessionFactory</literal> en
utilisant un lookup JNDI.
+ </para>
+
+ <para>
+ Nous recommandons que vous liiez la
<literal>SessionFactory</literal> � JNDI dans les
+ environnements manag�s et que vous utilisiez un singleton
<literal>static</literal> si ce n'est pas le cas.
+ Pour isoler votre application de ces d�tails, nous vous recommandons
aussi de masquer
+ le code de lookup actuel pour une
<literal>SessionFactory</literal> dans une classe helper,
+ comme <literal>HibernateUtil.getSessionFactory()</literal>.
Notez qu'une telle classe
+ est aussi un moyen efficace de d�marrer Hibernate—voir chapitre
1.
+ </para>
+ </sect2>
+
+ <sect2 id="configuration-j2ee-currentsession"
revision="4">
+ <title>Association automatique de la Session � JTA</title>
+
+ <para>
+ Le moyen le plus simple de g�rer les
<literal>Session</literal>s et transactions est
+ la gestion automatique de session "courante" offerte par
Hibernate.
+ Voir d�tail � <xref
linkend="architecture-current-session">current sessions</xref>.
+ En utilisant le contexte de session
<literal>"jta"</literal> session context, s'il n'y a pas
+ de <literal>Session</literal> associ�e � la transaction JTA
courante, une session sera
+ d�marr�e et associ�e � la transaction JTA courante la premi�re fois que
vous appelez
+ <literal>sessionFactory.getCurrentSession()</literal>. Les
<literal>Session</literal>s
+ obtenue via <literal>getCurrentSession()</literal> dans une
contexte <literal>"jta"</literal>
+ seront automatiquement flush�es avant la validation de la transaction,
ferm�es une fois
+ la transaction compl�t�e, et lib�reront les connexions JDBC de mani�re
aggressive
+ apr�s chaque statement. Ceci permet aux
<literal>Session</literal>s d'�tre
+ g�r�es par le cycle de vie de la transaction JTA � la quelle est sont
associ�es,
+ laissant le code de l'utilisateur propre de ce type de gestion. Votre
code peut
+ soit utiliser JTA de mani�re programmatique via
<literal>UserTransaction</literal>, ou (ce qui est recommand�
+ pour la portabilit� du code) utiliser l'API
<literal>Transaction</literal> API pour marquer
+ les limites. Si vous ex�cutez sous un conteneur EJB, la d�marcation
d�clarative des transactions
+ avec CMT est recommand�e.
+ </para>
+
+ </sect2>
+
+ <sect2 id="configuration-j2ee-jmx" revision="1">
+ <title>D�ploiement JMX</title>
+
+ <para>
+ La ligne <literal>cfg.buildSessionFactory()</literal> doit
toujours �tre ex�cut�e
+ quelque part pour avoir une <literal>SessionFactory</literal>
dans JNDI. Vous pouvez
+ faire cela dans un bloc d'initialisation
<literal>static</literal> (comme
+ celui qui se trouve dans la classe
<literal>HibernateUtil</literal>) ou vous pouvez
+ d�ployer Hibernate en temps que <emphasis>service
manag�</emphasis>.
+ </para>
+
+ <para>
+ Hibernate est distribu� avec
<literal>org.hibernate.jmx.HibernateService</literal>
+ pour le d�ploiement sur un serveur d'application avec le support de
JMX comme JBoss AS.
+ Le d�ploiement et la configuration sont sp�cifiques � chaque vendeur.
Voici un fichier
+ <literal>jboss-service.xml</literal> d'exemple pour JBoss
4.0.x:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<server>
+
+<mbean code="org.hibernate.jmx.HibernateService"
+ name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
+
+ <!-- Required services -->
+ <depends>jboss.jca:service=RARDeployer</depends>
+ <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
+
+ <!-- Bind the Hibernate service to JNDI -->
+ <attribute
name="JndiName">java:/hibernate/SessionFactory</attribute>
+
+ <!-- Datasource settings -->
+ <attribute name="Datasource">java:HsqlDS</attribute>
+ <attribute
name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
+
+ <!-- Transaction integration -->
+ <attribute name="TransactionStrategy">
+ org.hibernate.transaction.JTATransactionFactory</attribute>
+ <attribute name="TransactionManagerLookupStrategy">
+ org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
+ <attribute
name="FlushBeforeCompletionEnabled">true</attribute>
+ <attribute name="AutoCloseSessionEnabled">true</attribute>
+
+ <!-- Fetching options -->
+ <attribute name="MaximumFetchDepth">5</attribute>
+
+ <!-- Second-level caching -->
+ <attribute name="SecondLevelCacheEnabled">true</attribute>
+ <attribute
name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
+ <attribute name="QueryCacheEnabled">true</attribute>
+
+ <!-- Logging -->
+ <attribute name="ShowSqlEnabled">true</attribute>
+
+ <!-- Mapping files -->
+ <attribute
name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
+
+</mbean>
+
+</server>]]></programlisting>
+
+ <para>
+ Ce fichier est d�ploy� dans un r�pertoire
<literal>META-INF</literal> et est packag�
+ dans un fichier JAR avec l'extension
<literal>.sar</literal> (service archive).
+ Vous devez �galement packager Hibernate, les librairies tierces requises,
vos classes
+ persistantes compil�es et vos fichiers de mapping dans la m�me archive.
Vos beans
+ entreprise (souvent des EJBs session) peuvent rester dans leur propre
fichier JAR mais
+ vous pouvez inclure ce fichier JAR dans le jar principal du service pour
avoir une seule unit�
+ d�ployable � chaud. Vous pouvez consulter la documentation de JBoss AS
pour plus d'information
+ sur les services JMX et le d�ploiement des EJBs.
+ </para>
+
+ </sect2>
+
+
+ </sect1>
+
+
+
+
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/events.xml (from
rev 14070, core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/events.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/events.xml
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/content/events.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="events">
+ <title>Les intercepteurs et les �v�nements</title>
+
+ <para>
+ Il est souvent utile pour l'application de r�agir � certains �v�nements
+ qui surviennent dans Hibernate. Cela autorise l'impl�mentation de certaines
sortes de
+ fonctionnalit�s g�n�riques, et d'extensions de fonctionnalit�s
d'Hibernate.
+ </para>
+
+ <sect1 id="objectstate-interceptors" revision="2">
+ <title>Intercepteurs</title>
+
+ <para>
+ L'interface <literal>Interceptor</literal> fournit des
"callbacks" de la session vers l'application
+ et permettent � l'application de consulter et/ou de manipuler des
propri�t�s
+ d'un objet persistant avant qu'il soit sauvegard�, mis � jour,
supprim� ou charg�.
+ Une utilisation possible de cette fonctionnalit� est de tracer l'acc�s �
l'information.
+ Par exemple, l'<literal>Interceptor</literal> suivant
positionne
+ <literal>createTimestamp</literal> quand un
<literal>Auditable</literal> est cr��
+ et met � jour la propri�t� <literal>lastUpdateTimestamp</literal>
quand un
+ <literal>Auditable</literal> est mis � jour.
+ </para>
+
+ <para>
+ Vous pouvez soit impl�menter <literal>Interceptor</literal>
directement ou (mieux)
+ �tendre <literal>EmptyInterceptor</literal>.
+ </para>
+
+ <programlisting><![CDATA[package org.hibernate.test;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Transaction;
+import org.hibernate.type.Type;
+
+public class AuditInterceptor extends EmptyInterceptor {
+
+ private int updates;
+ private int creates;
+ private int loads;
+
+ public void onDelete(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ // ne fait rien
+ }
+
+ public boolean onFlushDirty(Object entity,
+ Serializable id,
+ Object[] currentState,
+ Object[] previousState,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ updates++;
+ for ( int i=0; i < propertyNames.length; i++ ) {
+ if ( "lastUpdateTimestamp".equals( propertyNames[i] ) ) {
+ currentState[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+ if ( entity instanceof Auditable ) {
+ loads++;
+ }
+ return false;
+ }
+
+ public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if ( entity instanceof Auditable ) {
+ creates++;
+ for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( "createTimestamp".equals( propertyNames[i] ) ) {
+ state[i] = new Date();
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void postFlush(Iterator entities) {
+ System.out.println("Creations: " + creates + ", Updates: " +
updates);
+ }
+
+ public void afterTransactionCompletion(Transaction tx) {
+ if ( tx.wasCommitted() ) {
+ System.out.println("Creations: " + creates + ", Updates:
" + updates, "Loads: " + loads);
+ }
+ updates=0;
+ creates=0;
+ loads=0;
+ }
+
+}]]></programlisting>
+
+ <para>
+ L'intercepteur doit �tre sp�cifi� quand une session est cr��e.
+ </para>
+
+ <programlisting><![CDATA[Session session = sf.openSession( new
AuditInterceptor() );]]></programlisting>
+
+ <para>
+ Vous pouvez aussi mettre un intercepteur au niveau global, en utilisant
l'objet <literal>Configuration</literal>.
+ Dans ce cas, l'intercepteur doit �tre "threadsafe".
+ </para>
+
+ <programlisting><![CDATA[new Configuration().setInterceptor( new
AuditInterceptor() );]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="objectstate-events" revision="3">
+ <title>Syst�me d'�v�nements</title>
+
+ <para>
+ Si vous devez r�agir � des �v�nements particuliers dans votre couche de
persistance,
+ vous pouvez aussi utiliser l'architecture
d'<emphasis>�v�nements</emphasis> d'Hibernate3.
+ Le syst�me d'�v�nements peut �tre utilis� en suppl�ment ou en
remplacement des interceptors.
+ </para>
+
+ <para>
+ Essentiellement toutes les m�thodes de l'interface
<literal>Session</literal> sont corr�l�es �
+ un �v�nement. Vous avez un <literal>LoadEvent</literal>, un
<literal>FlushEvent</literal>, etc
+ (consultez la DTD du fichier de configuration XML ou le paquet
<literal>org.hibernate.event</literal>
+ pour avoir la liste compl�te des types d'�v�nement d�finis).
+ Quand une requ�te est faite � partir d'une de ces m�thodes, la
+ <literal>Session</literal> Hibernate g�n�re un �v�nement
appropri� et le passe
+ au listener configur� pour ce type.
+ Par d�faut, ces listeners impl�mentent le m�me traitement dans lequel ces
m�thodes
+ aboutissent toujours.
+ Cependant, vous �tes libre d'impl�menter une version personnalis�e
d'une de ces
+ interfaces de listener (c'est-�-dire, le
<literal>LoadEvent</literal> est trait� par
+ l'impl�mentation de l'interface
<literal>LoadEventListener</literal> d�clar�e), dans
+ quel cas leur impl�mentation devrait �tre responsable du traitement des
+ requ�tes <literal>load()</literal> faites par la
<literal>Session</literal>.
+ </para>
+
+ <para>
+ Les listeners devraient effectivement �tre consid�r�s comme des singletons ;
dans le sens
+ o� ils sont partag�s entre des requ�tes, et donc ne devraient pas sauvegarder
des �tats
+ de variables d'instance.
+ </para>
+
+ <para>
+ Un listener personnalis� devrait impl�menter l'interface appropri�e pour
l'�v�nement
+ qu'il veut traiter et/ou �tendre une des classes de base (ou m�me
l'�v�nement pr�t �
+ l'emploi utilis� par Hibernate comme ceux d�clar�s non-finaux � cette
intention). Les
+ listeners personnalis�s peuvent �tre soit inscrits par programmation �
travers l'objet
+ <literal>Configuration</literal>, ou sp�cifi�s la configuration
XML d'Hibernate
+ (la configuration d�clarative � travers le fichier de propri�t�s n'est
pas support�e).
+ Voici un exemple de listener personnalis� pour l'�v�nement de chargement
:
+ </para>
+
+ <programlisting><![CDATA[public class MyLoadListener implements
LoadEventListener {
+ // C'est une simple m�thode d�finie par l'interface LoadEventListener
+ public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType)
+ throws HibernateException {
+ if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() )
) {
+ throw MySecurityException("Unauthorized access");
+ }
+ }
+}]]></programlisting>
+
+ <para>
+ Vous avez aussi besoin d'une entr�e de configuration disant � Hibernate
d'utiliser
+ ce listener en plus du listener par d�faut :
+ </para>
+
+<programlisting><![CDATA[<hibernate-configuration>
+ <session-factory>
+ ...
+ <event type="load">
+ <listener class="com.eg.MyLoadListener"/>
+ <listener
class="org.hibernate.event.def.DefaultLoadEventListener"/>
+ </event>
+ </session-factory>
+</hibernate-configuration>]]></programlisting>
+
+ <para>
+ Vous pouvez aussi l'inscrire par programmation :
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = new Configuration();
+LoadEventListener[] stack = { new MyLoadListener(), new DefaultLoadEventListener() };
+cfg.EventListeners().setLoadEventListeners(stack);]]></programlisting>
+
+ <para>
+ Les listeners inscrits d�clarativement ne peuvent pas partager
d'instances. Si le m�me
+ nom de classe est utilis�e dans plusieurs �l�ments
<literal><listener/></literal>,
+ chaque r�f�rence sera une instance distincte de cette classe. Si vous avez
besoin de la
+ facult� de partager des instances de listener entre plusieurs types de
listener, vous devez
+ utiliser l'approche d'inscription par programmation.
+ </para>
+
+ <para>
+ Pourquoi impl�menter une interface et d�finir le type sp�cifique durant la
configuration ?
+ Une impl�mentation de listener pourrait impl�menter plusieurs interfaces de
listener
+ d'�v�nements. Avoir en plus le type d�fini durant l'inscription rend
plus facile
+ l'activation ou la d�sactivation pendant la configuration.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-decl-security" revision="2">
+ <title>S�curit� d�clarative d'Hibernate</title>
+ <para>
+ G�n�ralement, la s�curit� d�clarative dans les applications Hibernate est
g�r�e dans la
+ couche de session. Maintenant, Hibernate3 permet � certaines actions
d'�tre approuv�es
+ via JACC, et autoris�es via JAAS. Cette fonctionnalit� optionnelle est
construite
+ au dessus de l'architecture d'�v�nements.
+ </para>
+
+ <para>
+ D'abord, vous devez configurer les listeners d'�v�nements appropri�s
pour permettre
+ l'utilisation d'autorisations JAAS.
+ </para>
+
+ <programlisting><![CDATA[<listener type="pre-delete"
class="org.hibernate.secure.JACCPreDeleteEventListener"/>
+<listener type="pre-update"
class="org.hibernate.secure.JACCPreUpdateEventListener"/>
+<listener type="pre-insert"
class="org.hibernate.secure.JACCPreInsertEventListener"/>
+<listener type="pre-load"
class="org.hibernate.secure.JACCPreLoadEventListener"/>]]></programlisting>
+
+ <para>
+ Notez que <literal><listener type="..."
class="..."/></literal> est juste un raccourci
+ pour <literal><event
type="..."><listener
class="..."/></event></literal>
+ quand il y a exactement un listener pour un type d'�v�nement
particulier.
+ </para>
+
+ <para>
+ Ensuite, toujours dans <literal>hibernate.cfg.xml</literal>, lier
les permissions aux r�les :
+ </para>
+
+ <programlisting><![CDATA[<grant role="admin"
entity-name="User" actions="insert,update,read"/>
+<grant role="su" entity-name="User"
actions="*"/>]]></programlisting>
+
+ <para>
+ Les noms de r�le sont les r�les compris par votre fournisseur JAAC.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied:
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_mappings.xml (from
rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/example_mappings.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_mappings.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_mappings.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,672 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<chapter id="example-mappings">
+ <title>Exemple : quelques mappings</title>
+
+ <para>
+ Ce chapitre montre quelques mappings plus complexes.
+ </para>
+
+ <sect1 id="example-mappings-emp">
+ <title>Employeur/Employ� (Employer/Employee)</title>
+
+ <para>
+ Le mod�le suivant de relation entre <literal>Employer</literal>
et
+ <literal>Employee</literal> utilise une vraie classe entit�
(<literal>Employment</literal>)
+ pour repr�senter l'association. On a fait cela parce qu'il peut y
avoir plus d'une p�riode
+ d'emploi pour les deux m�mes parties. Des composants sont utilis�s pour
mod�liser les
+ valeurs mon�taires et les noms des employ�s.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/EmployerEmployee.gif"
format="GIF" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/EmployerEmployee.gif"
format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ Voici un document de mapping possible :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Employer" table="employers">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employer_id_seq</param>
+ </generator>
+ </id>
+ <property name="name"/>
+ </class>
+
+ <class name="Employment" table="employment_periods">
+
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employment_id_seq</param>
+ </generator>
+ </id>
+ <property name="startDate" column="start_date"/>
+ <property name="endDate" column="end_date"/>
+
+ <component name="hourlyRate" class="MonetaryAmount">
+ <property name="amount">
+ <column name="hourly_rate" sql-type="NUMERIC(12,
2)"/>
+ </property>
+ <property name="currency" length="12"/>
+ </component>
+
+ <many-to-one name="employer" column="employer_id"
not-null="true"/>
+ <many-to-one name="employee" column="employee_id"
not-null="true"/>
+
+ </class>
+
+ <class name="Employee" table="employees">
+ <id name="id">
+ <generator class="sequence">
+ <param name="sequence">employee_id_seq</param>
+ </generator>
+ </id>
+ <property name="taxfileNumber"/>
+ <component name="name" class="Name">
+ <property name="firstName"/>
+ <property name="initial"/>
+ <property name="lastName"/>
+ </component>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Et voici le sch�ma des tables g�n�r�es par
<literal>SchemaExport</literal>.
+ </para>
+
+ <programlisting><![CDATA[create table employers (
+ id BIGINT not null,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table employment_periods (
+ id BIGINT not null,
+ hourly_rate NUMERIC(12, 2),
+ currency VARCHAR(12),
+ employee_id BIGINT not null,
+ employer_id BIGINT not null,
+ end_date TIMESTAMP,
+ start_date TIMESTAMP,
+ primary key (id)
+)
+
+create table employees (
+ id BIGINT not null,
+ firstName VARCHAR(255),
+ initial CHAR(1),
+ lastName VARCHAR(255),
+ taxfileNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table employment_periods
+ add constraint employment_periodsFK0 foreign key (employer_id) references employers
+alter table employment_periods
+ add constraint employment_periodsFK1 foreign key (employee_id) references employees
+create sequence employee_id_seq
+create sequence employment_id_seq
+create sequence employer_id_seq]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-authorwork">
+ <title>Auteur/Travail (Author/Work)</title>
+
+ <para>
+ Soit le mod�le de la relation entre <literal>Work</literal>,
<literal>Author</literal>
+ et <literal>Person</literal>. Nous repr�sentons la relation entre
<literal>Work</literal>
+ et <literal>Author</literal> comme une association
plusieurs-vers-plusieurs. Nous avons choisi de
+ repr�senter la relation entre <literal>Author</literal> et
<literal>Person</literal>
+ comme une association un-vers-un. Une autre possibilit� aurait �t� que
+ <literal>Author</literal> h�rite de
<literal>Person</literal>.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/AuthorWork.gif"
format="GIF" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/AuthorWork.gif"
format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ Le mapping suivant repr�sente exactement ces relations :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Work" table="works"
discriminator-value="W">
+
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <discriminator column="type" type="character"/>
+
+ <property name="title"/>
+ <set name="authors" table="author_work">
+ <key column name="work_id"/>
+ <many-to-many class="Author" column
name="author_id"/>
+ </set>
+
+ <subclass name="Book" discriminator-value="B">
+ <property name="text"/>
+ </subclass>
+
+ <subclass name="Song" discriminator-value="S">
+ <property name="tempo"/>
+ <property name="genre"/>
+ </subclass>
+
+ </class>
+
+ <class name="Author" table="authors">
+
+ <id name="id" column="id">
+ <!-- The Author must have the same identifier as the Person -->
+ <generator class="assigned"/>
+ </id>
+
+ <property name="alias"/>
+ <one-to-one name="person" constrained="true"/>
+
+ <set name="works" table="author_work"
inverse="true">
+ <key column="author_id"/>
+ <many-to-many class="Work" column="work_id"/>
+ </set>
+
+ </class>
+
+ <class name="Person" table="persons">
+ <id name="id" column="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Il y a quatre tables dans ce mapping. <literal>works</literal>,
+ <literal>authors</literal> et <literal>persons</literal>
qui contiennent
+ respectivement les donn�es de work, author et person.
+ <literal>author_work</literal> est une table d'association qui
lie authors
+ � works. Voici le sch�ma de tables, g�n�r� par
<literal>SchemaExport</literal>.
+ </para>
+
+ <programlisting><![CDATA[create table works (
+ id BIGINT not null generated by default as identity,
+ tempo FLOAT,
+ genre VARCHAR(255),
+ text INTEGER,
+ title VARCHAR(255),
+ type CHAR(1) not null,
+ primary key (id)
+)
+
+create table author_work (
+ author_id BIGINT not null,
+ work_id BIGINT not null,
+ primary key (work_id, author_id)
+)
+
+create table authors (
+ id BIGINT not null generated by default as identity,
+ alias VARCHAR(255),
+ primary key (id)
+)
+
+create table persons (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+alter table authors
+ add constraint authorsFK0 foreign key (id) references persons
+alter table author_work
+ add constraint author_workFK0 foreign key (author_id) references authors
+alter table author_work
+ add constraint author_workFK1 foreign key (work_id) references
works]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-mappings-customerorderproduct">
+ <title>Client/Commande/Produit (Customer/Order/Product)</title>
+
+ <para>
+ Imaginons maintenant le mod�le de relation entre
<literal>Customer</literal>,
+ <literal>Order</literal>, <literal>LineItem</literal>
et <literal>Product</literal>.
+ Il y a une association un-vers-plusieurs entre
<literal>Customer</literal> et
+ <literal>Order</literal>, mais comment devrions nous repr�senter
<literal>Order</literal> /
+ <literal>LineItem</literal> /
<literal>Product</literal>? J'ai choisi de mapper
+ <literal>LineItem</literal> comme une classe d'association
repr�sentant l'association
+ plusieurs-vers-plusieurs entre <literal>Order</literal> et
<literal>Product</literal>. Dans
+ Hibernate, on appelle cela un �l�ment composite.
+ </para>
+
+ <mediaobject>
+ <imageobject role="fo">
+ <imagedata fileref="../images/CustomerOrderProduct.gif"
format="GIF" align="center"/>
+ </imageobject>
+ <imageobject role="html">
+ <imagedata fileref="../images/CustomerOrderProduct.gif"
format="GIF" align="center"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>
+ Le document de mapping :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Customer" table="customers">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ <set name="orders" inverse="true">
+ <key column="customer_id"/>
+ <one-to-many class="Order"/>
+ </set>
+ </class>
+
+ <class name="Order" table="orders">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="date"/>
+ <many-to-one name="customer" column="customer_id"/>
+ <list name="lineItems" table="line_items">
+ <key column="order_id"/>
+ <list-index column="line_number"/>
+ <composite-element class="LineItem">
+ <property name="quantity"/>
+ <many-to-one name="product"
column="product_id"/>
+ </composite-element>
+ </list>
+ </class>
+
+ <class name="Product" table="products">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="serialNumber"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ <literal>customers</literal>, <literal>orders</literal>,
<literal>line_items</literal> et
+ <literal>products</literal> contiennent les donn�es de customer,
order, order line item et product.
+ <literal>line_items</literal> est aussi la table d'association
liant orders � products.
+ </para>
+
+ <programlisting><![CDATA[create table customers (
+ id BIGINT not null generated by default as identity,
+ name VARCHAR(255),
+ primary key (id)
+)
+
+create table orders (
+ id BIGINT not null generated by default as identity,
+ customer_id BIGINT,
+ date TIMESTAMP,
+ primary key (id)
+)
+
+create table line_items (
+ line_number INTEGER not null,
+ order_id BIGINT not null,
+ product_id BIGINT,
+ quantity INTEGER,
+ primary key (order_id, line_number)
+)
+
+create table products (
+ id BIGINT not null generated by default as identity,
+ serialNumber VARCHAR(255),
+ primary key (id)
+)
+
+alter table orders
+ add constraint ordersFK0 foreign key (customer_id) references customers
+alter table line_items
+ add constraint line_itemsFK0 foreign key (product_id) references products
+alter table line_items
+ add constraint line_itemsFK1 foreign key (order_id) references
orders]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="misc">
+ <title>Divers mappings d'exemple</title>
+
+ <para>
+ Ces exemples sont tous pris de la suite de tests d'Hibernate. Vous en
trouverez beaucoup d'autres.
+ Regardez dans le dossier <literal>test</literal> de la
distribution d'Hibernate.
+ </para>
+
+ <para>TODO: put words around this stuff</para>
+
+ <sect2 id="example-mappings-typed-onetone">
+ <title>"Typed" one-to-one association</title>
+<programlisting><![CDATA[<class name="Person">
+ <id name="name"/>
+ <one-to-one name="address"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'HOME'</formula>
+ </one-to-one>
+ <one-to-one name="mailingAddress"
+ cascade="all">
+ <formula>name</formula>
+ <formula>'MAILING'</formula>
+ </one-to-one>
+</class>
+
+<class name="Address" batch-size="2"
+ check="addressType in ('MAILING', 'HOME',
'BUSINESS')">
+ <composite-id>
+ <key-many-to-one name="person"
+ column="personName"/>
+ <key-property name="type"
+ column="addressType"/>
+ </composite-id>
+ <property name="street" type="text"/>
+ <property name="state"/>
+ <property name="zip"/>
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key">
+ <title>Exemple de clef compos�e</title>
+<programlisting><![CDATA[<class name="Customer">
+
+ <id name="customerId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="name" not-null="true"
length="100"/>
+ <property name="address" not-null="true"
length="200"/>
+
+ <list name="orders"
+ inverse="true"
+ cascade="save-update">
+ <key column="customerId"/>
+ <index column="orderNumber"/>
+ <one-to-many class="Order"/>
+ </list>
+
+</class>
+
+<class name="Order" table="CustomerOrder"
lazy="true">
+ <synchronize table="LineItem"/>
+ <synchronize table="Product"/>
+
+ <composite-id name="id"
+ class="Order$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ </composite-id>
+
+ <property name="orderDate"
+ type="calendar_date"
+ not-null="true"/>
+
+ <property name="total">
+ <formula>
+ ( select sum(li.quantity*p.price)
+ from LineItem li, Product p
+ where li.productId = p.productId
+ and li.customerId = customerId
+ and li.orderNumber = orderNumber )
+ </formula>
+ </property>
+
+ <many-to-one name="customer"
+ column="customerId"
+ insert="false"
+ update="false"
+ not-null="true"/>
+
+ <bag name="lineItems"
+ fetch="join"
+ inverse="true"
+ cascade="save-update">
+ <key>
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </key>
+ <one-to-many class="LineItem"/>
+ </bag>
+
+</class>
+
+<class name="LineItem">
+
+ <composite-id name="id"
+ class="LineItem$Id">
+ <key-property name="customerId" length="10"/>
+ <key-property name="orderNumber"/>
+ <key-property name="productId" length="10"/>
+ </composite-id>
+
+ <property name="quantity"/>
+
+ <many-to-one name="order"
+ insert="false"
+ update="false"
+ not-null="true">
+ <column name="customerId"/>
+ <column name="orderNumber"/>
+ </many-to-one>
+
+ <many-to-one name="product"
+ insert="false"
+ update="false"
+ not-null="true"
+ column="productId"/>
+
+</class>
+
+<class name="Product">
+ <synchronize table="LineItem"/>
+
+ <id name="productId"
+ length="10">
+ <generator class="assigned"/>
+ </id>
+
+ <property name="description"
+ not-null="true"
+ length="200"/>
+ <property name="price" length="3"/>
+ <property name="numberAvailable"/>
+
+ <property name="numberOrdered">
+ <formula>
+ ( select sum(li.quantity)
+ from LineItem li
+ where li.productId = productId )
+ </formula>
+ </property>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-composite-key-manytomany">
+ <title>Many-to-many avec une clef compos�e partag�e</title>
+<programlisting><![CDATA[<class name="User"
table="`User`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <set name="groups" table="UserGroup">
+ <key>
+ <column name="userName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="Group">
+ <column name="groupName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+
+<class name="Group" table="`Group`">
+ <composite-id>
+ <key-property name="name"/>
+ <key-property name="org"/>
+ </composite-id>
+ <property name="description"/>
+ <set name="users" table="UserGroup"
inverse="true">
+ <key>
+ <column name="groupName"/>
+ <column name="org"/>
+ </key>
+ <many-to-many class="User">
+ <column name="userName"/>
+ <formula>org</formula>
+ </many-to-many>
+ </set>
+</class>
+]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-content-discrimination">
+ <title>Contenu bas� sur une discrimination</title>
+<programlisting><![CDATA[<class name="Person"
+ discriminator-value="P">
+
+ <id name="id"
+ column="person_id"
+ unsaved-value="0">
+ <generator class="native"/>
+ </id>
+
+
+ <discriminator
+ type="character">
+ <formula>
+ case
+ when title is not null then 'E'
+ when salesperson is not null then 'C'
+ else 'P'
+ end
+ </formula>
+ </discriminator>
+
+ <property name="name"
+ not-null="true"
+ length="80"/>
+
+ <property name="sex"
+ not-null="true"
+ update="false"/>
+
+ <component name="address">
+ <property name="address"/>
+ <property name="zip"/>
+ <property name="country"/>
+ </component>
+
+ <subclass name="Employee"
+ discriminator-value="E">
+ <property name="title"
+ length="20"/>
+ <property name="salary"/>
+ <many-to-one name="manager"/>
+ </subclass>
+
+ <subclass name="Customer"
+ discriminator-value="C">
+ <property name="comments"/>
+ <many-to-one name="salesperson"/>
+ </subclass>
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="example-mappings-association-alternatekeys"
revision="2">
+ <title>Associations sur des clefs altern�es</title>
+<programlisting><![CDATA[<class name="Person">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="name" length="100"/>
+
+ <one-to-one name="address"
+ property-ref="person"
+ cascade="all"
+ fetch="join"/>
+
+ <set name="accounts"
+ inverse="true">
+ <key column="userId"
+ property-ref="userId"/>
+ <one-to-many class="Account"/>
+ </set>
+
+ <property name="userId" length="8"/>
+
+</class>
+
+<class name="Address">
+
+ <id name="id">
+ <generator class="hilo"/>
+ </id>
+
+ <property name="address" length="300"/>
+ <property name="zip" length="5"/>
+ <property name="country" length="25"/>
+ <many-to-one name="person" unique="true"
not-null="true"/>
+
+</class>
+
+<class name="Account">
+ <id name="accountId" length="32">
+ <generator class="uuid"/>
+ </id>
+
+ <many-to-one name="user"
+ column="userId"
+ property-ref="userId"/>
+
+ <property name="type" not-null="true"/>
+
+</class>]]></programlisting>
+ </sect2>
+
+ </sect1>
+
+</chapter>
+
Copied:
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_parentchild.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/example_parentchild.xml)
===================================================================
---
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_parentchild.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_parentchild.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,372 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="example-parentchild">
+ <title>Exemple : P�re/Fils</title>
+
+ <para>
+ L'une des premi�res choses que les nouveaux utilisateurs essaient de faire
avec Hibernate est de mod�liser
+ une relation p�re/fils. Il y a deux approches diff�rentes pour cela. Pour un
certain nombre de raisons, la m�thode la
+ plus courante, en particulier pour les nouveaux utilisateurs, est de mod�liser
les deux relations <literal>P�re</literal>
+ et <literal>Fils</literal> comme des classes entit�s li�es par une
association <literal><one-to-many></literal> du
+ <literal>P�re</literal> vers le <literal>Fils</literal>
(l'autre approche est de d�clarer le <literal>Fils</literal>
+ comme un <literal><composite-element></literal>). Il
est �vident que le sens de l'association un vers plusieurs
+ (dans Hibernate) est bien moins proche du sens habituel d'une relation
p�re/fils que ne l'est celui d'un
+ �l�ment cmposite. Nous allons vous expliquer comment utiliser une association
<emphasis>un vers plusieurs bidirectionnelle
+ avec cascade</emphasis> afin de mod�liser efficacement et �l�gamment une
relation p�re/fils, ce n'est vraiment
+ pas difficile !
+ </para>
+
+ <sect1 id="example-parentchild-collections">
+ <title>Une note � propos des collections</title>
+
+ <para>
+ Les collections Hibernate sont consid�r�es comme �tant une partie logique
+ de l'entit� dans laquelle elles sont contenues ; jamais des entit�s
qu'elle
+ contient. C'est une distinction crutiale ! Les cons�quences sont les
suivantes :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Quand nous ajoutons / retirons un objet d'une collection, le
num�ro de version du
+ propri�taire de la collection est incr�ment�.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Si un objet qui a �t� enlev� d'une collection est une instance de
type valeur (ex :
+ �l�ment composite), cet objet cessera d'�tre persistant et son
�tat sera compl�tement effac�
+ de la base de donn�es. Par ailleurs, ajouter une instance de type
valeur dans une collection
+ aura pour cons�quence que son �tat sera imm�diatement persistant.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Si une entit� est enlev�e d'une collection (association
un-vers-plusieurs
+ ou plusieurs-vers-plusieurs), par d�faut, elle ne sera pas effac�e.
Ce comportement
+ est compl�tement logique - une modification de l'un des �tats
internes d'une entit�
+ ne doit pas causer la disparition de l'entit� associ�e !
+ De m�me, l'ajout d'une entit� dans une collection
n'engendre pas,
+ par d�faut, la persistance de cette entit�.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Le comportement par d�faut est donc que l'ajout d'une entit� dans une
collection cr��
+ simplement le lien entre les deux entit�s, et qu'effacer une entit�
supprime ce lien.
+ C'est le comportement le plus appropri� dans la plupart des cas. Ce
comportement n'est
+ cependant pas appropri� lorsque la vie du fils est li�e au cycle de vie du
p�re.
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-bidir">
+ <title>un-vers-plusieurs bidirectionnel</title>
+
+ <para>
+ Supposons que nous ayons une simple association
<literal><one-to-many></literal>
+ de <literal>Parent</literal> vers
<literal>Child</literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+ </set>]]></programlisting>
+
+ <para>
+ Si nous executions le code suivant
+ </para>
+
+ <programlisting><![CDATA[Parent p = .....;
+Child c = new Child();
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Hibernate ex�cuterait deux ordres SQL:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>un <literal>INSERT</literal> pour cr�er
l'enregistrement pour <literal>c</literal></para>
+ </listitem>
+ <listitem>
+ <para>
+ un <literal>UPDATE</literal> pour cr�er le lien de
<literal>p</literal> vers
+ <literal>c</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Ceci est non seuleument inefficace, mais viole aussi toute contrainte
<literal>NOT NULL</literal> sur
+ la colonne <literal>parent_id</literal>. Nous pouvons r�parer la
contrainte de nullit�
+ en sp�cifiant <literal>not-null="true"</literal> dans
le mapping de la collection :
+ </para>
+
+ <programlisting><![CDATA[<set name="children">
+ <key column="parent_id" not-null="true"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ Cependant ce n'est pas la solution recommand�e.
+ </para>
+
+ <para>
+ La cause sous jacente � ce comportement est que le lien (la cl� �trang�re
<literal>parent_id</literal>) de
+ <literal>p</literal> vers <literal>c</literal>
n'est pas consid�r�e comme faisant partie de l'�tat
+ de l'objet <literal>Child</literal> et n'est donc pas
cr�� par l'<literal>INSERT</literal>.
+ La solution est donc que ce lien fasse partie du mapping de
<literal>Child</literal>.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="parent"
column="parent_id" not-null="true"/>]]></programlisting>
+
+ <para>
+ (Nous avons aussi besoin d'ajouter la propri�t�
<literal>parent</literal> dans la classe
<literal>Child</literal>).
+ </para>
+
+ <para>
+ Maintenant que l'�tat du lien est g�r� par l'entit�
<literal>Child</literal>, nous sp�cifions � la
+ collection de ne pas mettre � jour le lien. Nous utilisons l'attribut
<literal>inverse</literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="children"
inverse="true">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ Le code suivant serait utilis� pour ajouter un nouveau
<literal>Child</literal>
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class,
pid);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Maintenant, seul un <literal>INSERT</literal> SQL est n�cessaire
!
+ </para>
+
+ <para>
+ Pour all�ger encore un peu les choses, nous devrions cr�er une m�thode
<literal>addChild()</literal>
+ dans <literal>Parent</literal>.
+ </para>
+
+ <programlisting><![CDATA[public void addChild(Child c) {
+ c.setParent(this);
+ children.add(c);
+}]]></programlisting>
+
+ <para>
+ Le code d'ajout d'un <literal>Child</literal> serait
alors
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class,
pid);
+Child c = new Child();
+p.addChild(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-cascades">
+ <title>Cycle de vie en cascade</title>
+
+ <para>
+ L'appel explicite de <literal>save()</literal> est un peu
fastidieux. Nous pouvons
+ simplifier cela en utilisant les cascades.
+ </para>
+
+ <programlisting><![CDATA[<set name="children"
inverse="true" cascade="all">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ Simplifie le code pr�c�dent en
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class,
pid);
+Child c = new Child();
+p.addChild(c);
+session.flush();]]></programlisting>
+
+ <para>
+ De la m�me mani�re, nous n'avons pas � it�rer sur les fils lorsque nous
sauvons
+ ou effacons un <literal>Parent</literal>. Le code suivant efface
<literal>p</literal>
+ et tous ses fils de la base de donn�es.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class,
pid);
+session.delete(p);
+session.flush();]]></programlisting>
+
+ <para>
+ Par contre, ce code
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class,
pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+c.setParent(null);
+session.flush();]]></programlisting>
+
+ <para>
+ n'effacera pas <literal>c</literal> de la base de donn�es,
il enl�vera seulement
+ le lien vers <literal>p</literal> (et causera une violation de
contrainte
+ <literal>NOT NULL</literal>, dans ce cas).
+ Vous devez explicitement utiliser <literal>delete()</literal>
sur <literal>Child</literal>.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class,
pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+session.delete(c);
+session.flush();]]></programlisting>
+
+ <para>
+ Dans notre cas, un <literal>Child</literal> ne peut pas vraiment
exister sans son p�re. Si nous
+ effacons un <literal>Child</literal> de la collection, nous
voulons vraiment qu'il soit effac�.
+ Pour cela, nous devons utiliser
<literal>cascade="all-delete-orphan"</literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="children"
inverse="true" cascade="all-delete-orphan">
+ <key column="parent_id"/>
+ <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+ <para>
+ A noter : m�me si le mapping de la collection sp�cifie
<literal>inverse="true"</literal>, les cascades
+ sont toujours assur�es par l'it�ration sur les �l�ments de la collection.
Donc, si vous avez besoin
+ qu'un objet soit enregistr�, effac� ou mis � jour par cascade, vous devez
l'ajouter dans la colleciton.
+ Il ne suffit pas d'appeler explicitement
<literal>setParent()</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="example-parentchild-update">
+ <title>Cascades et
<literal>unsaved-value</literal></title>
+
+ <para>
+ Supposons que nous ayons charg� un <literal>Parent</literal> dans
une <literal>Session</literal>,
+ que nous l'ayons ensuite modifi� et que voulions persiter ces
modifications dans une nouvelle session
+ en appelant <literal>update()</literal>.
+ Le <literal>Parent</literal> contiendra une collection de fils
et, puisque la cascade est activ�e,
+ Hibernate a besoin de savoir quels fils viennent d'�tre instanci�s et
quels fils proviennent de la base
+ de donn�es. Supposons aussi que <literal>Parent</literal> et
<literal>Child</literal> ont tous deux
+ des identifiants du type <literal>Long</literal>.
+ Hibernate utilisera la propri�t� de l'identifiant et la propri�t� de la
version/horodatage pour d�terminer quels fils sont nouveaux
+ (vous pouvez aussi utiliser la propri�t� version ou timestamp, voir
+ <xref linkend="manipulatingdata-updating-detached"/>).
+ <emphasis>Dans Hibernate3, il n'est plus n�cessaire de sp�cifier
+ une <literal>unsaved-value</literal>
explicitement.</emphasis>
+ </para>
+
+ <para>
+ Le code suivant mettra � jour <literal>parent</literal> et
<literal>child</literal>
+ et ins�rera <literal>newChild</literal>.
+ </para>
+
+ <programlisting><![CDATA[//parent et child ont �t� charg�s dans une
session pr�c�dente
+parent.addChild(child);
+Child newChild = new Child();
+parent.addChild(newChild);
+session.update(parent);
+session.flush();]]></programlisting>
+
+ <para>
+ Ceci est tr�s bien pour des identifiants g�n�r�s, mais qu'en est-il des
identifiants assign�s et des
+ identifiants compos�s ? C'est plus difficile,
+ puisqu'Hibernate ne peut pas utiliser la propri�t� de l'identifiant
pour distinguer un objet
+ nouvellement instanci� (avec un identifiant assign� par l'utilisateur)
d'un objet charg� dans une session pr�c�dente.
+ Dans ce cas, Hibernate utilisera soit la propri�t� de version ou
d'horodatage, soit effectuera vraiment une requ�te au cache
+ de second niveau, soit, dans le pire des cas, � la base de donn�es, pour voir
si la ligne existe.
+ </para>
+
+ <!-- undocumenting
+ <para>
+ There is one further possibility. The
<literal>Interceptor</literal> method named
+ <literal>isUnsaved()</literal> lets the application implement
its own strategy for distinguishing
+ newly instantiated objects. For example, you could define a base class for
your persistent classes.
+ </para>
+
+ <programlisting><![CDATA[public class Persistent {
+ private boolean _saved = false;
+ public void onSave() {
+ _saved=true;
+ }
+ public void onLoad() {
+ _saved=true;
+ }
+ ......
+ public boolean isSaved() {
+ return _saved;
+ }
+}]]></programlisting>
+
+ <para>
+ (The <literal>saved</literal> property is non-persistent.)
+ Now implement <literal>isUnsaved()</literal>, along with
<literal>onLoad()</literal>
+ and <literal>onSave()</literal> as follows.
+ </para>
+
+ <programlisting><![CDATA[public Boolean isUnsaved(Object entity) {
+ if (entity instanceof Persistent) {
+ return new Boolean( !( (Persistent) entity ).isSaved() );
+ }
+ else {
+ return null;
+ }
+}
+
+public boolean onLoad(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onLoad();
+ return false;
+}
+
+public boolean onSave(Object entity,
+ Serializable id,
+ Object[] state,
+ String[] propertyNames,
+ Type[] types) {
+
+ if (entity instanceof Persistent) ( (Persistent) entity ).onSave();
+ return false;
+}]]></programlisting>
+
+ <para>
+ Don't worry; in Hibernate3 you don't need to write any of this kind
of code if you don't want to.
+ </para>
+ -->
+ </sect1>
+
+ <sect1 id="example-parentchild-conclusion">
+ <title>Conclusion</title>
+
+ <para>
+ Il y a quelques principes � ma�triser dans ce chapitre et tout cela peut
para�tre d�routant la premi�re fois.
+ Cependant, dans la pratique, tout fonctionne parfaitement. La plupart des
applications Hibernate utilisent
+ le pattern p�re / fils.
+ </para>
+
+ <para>
+ Nous avons �voqu� une alternative dans le premier paragraphe. Aucun des
points trait�s pr�c�demment n'existe
+ dans le cas d'un mapping
<literal><composite-element></literal> qui poss�de exactement la
s�mantique
+ d'une relation p�re / fils. Malheureusement, il y a deux grandes
limitations pour les classes �l�ments
+ composites : les �l�ments composites ne peuvent contenir de collections, et
ils ne peuvent �tre les fils
+ d'entit�s autres que l'unique parent.
+ </para>
+
+ </sect1>
+
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_weblog.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/example_weblog.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_weblog.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/example_weblog.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,432 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="example-weblog">
+ <title>Exemple : application Weblog</title>
+
+ <sect1 id="example-weblog-classes">
+ <title>Classes persistantes</title>
+
+ <para>
+ Les classes persistantes representent un weblog, et un article post�
+ dans un weblog. Il seront mod�lis�s comme une relation p�re/fils
+ standard, mais nous allons utiliser un "bag" tri� au lieu d'un
set.
+
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.List;
+
+public class Blog {
+ private Long _id;
+ private String _name;
+ private List _items;
+
+ public Long getId() {
+ return _id;
+ }
+ public List getItems() {
+ return _items;
+ }
+ public String getName() {
+ return _name;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setItems(List list) {
+ _items = list;
+ }
+ public void setName(String string) {
+ _name = string;
+ }
+}]]></programlisting>
+
+ <programlisting><![CDATA[package eg;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+public class BlogItem {
+ private Long _id;
+ private Calendar _datetime;
+ private String _text;
+ private String _title;
+ private Blog _blog;
+
+ public Blog getBlog() {
+ return _blog;
+ }
+ public Calendar getDatetime() {
+ return _datetime;
+ }
+ public Long getId() {
+ return _id;
+ }
+ public String getText() {
+ return _text;
+ }
+ public String getTitle() {
+ return _title;
+ }
+ public void setBlog(Blog blog) {
+ _blog = blog;
+ }
+ public void setDatetime(Calendar calendar) {
+ _datetime = calendar;
+ }
+ public void setId(Long long1) {
+ _id = long1;
+ }
+ public void setText(String string) {
+ _text = string;
+ }
+ public void setTitle(String string) {
+ _title = string;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-mappings">
+ <title>Mappings Hibernate</title>
+
+ <para>
+ Le mapping XML doit maintenant �tre relativement simple � vos yeux.
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="Blog"
+ table="BLOGS">
+
+ <id
+ name="id"
+ column="BLOG_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="name"
+ column="NAME"
+ not-null="true"
+ unique="true"/>
+
+ <bag
+ name="items"
+ inverse="true"
+ order-by="DATE_TIME"
+ cascade="all">
+
+ <key column="BLOG_ID"/>
+ <one-to-many class="BlogItem"/>
+
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+ <class
+ name="BlogItem"
+ table="BLOG_ITEMS"
+ dynamic-update="true">
+
+ <id
+ name="id"
+ column="BLOG_ITEM_ID">
+
+ <generator class="native"/>
+
+ </id>
+
+ <property
+ name="title"
+ column="TITLE"
+ not-null="true"/>
+
+ <property
+ name="text"
+ column="TEXT"
+ not-null="true"/>
+
+ <property
+ name="datetime"
+ column="DATE_TIME"
+ not-null="true"/>
+
+ <many-to-one
+ name="blog"
+ column="BLOG_ID"
+ not-null="true"/>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="example-weblog-code">
+ <title>Code Hibernate</title>
+
+ <para>
+ La classe suivante montre quelques utilisations que nous pouvons faire
+ de ces classes.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+
+public class BlogMain {
+
+ private SessionFactory _sessions;
+
+ public void configure() throws HibernateException {
+ _sessions = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class)
+ .buildSessionFactory();
+ }
+
+ public void exportTables() throws HibernateException {
+ Configuration cfg = new Configuration()
+ .addClass(Blog.class)
+ .addClass(BlogItem.class);
+ new SchemaExport(cfg).create(true, true);
+ }
+
+ public Blog createBlog(String name) throws HibernateException {
+
+ Blog blog = new Blog();
+ blog.setName(name);
+ blog.setItems( new ArrayList() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.persist(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public BlogItem createBlogItem(Blog blog, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setBlog(blog);
+ item.setDatetime( Calendar.getInstance() );
+ blog.getItems().add(item);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(blog);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public BlogItem createBlogItem(Long blogid, String title, String text)
+ throws HibernateException {
+
+ BlogItem item = new BlogItem();
+ item.setTitle(title);
+ item.setText(text);
+ item.setDatetime( Calendar.getInstance() );
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ Blog blog = (Blog) session.load(Blog.class, blogid);
+ item.setBlog(blog);
+ blog.getItems().add(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return item;
+ }
+
+ public void updateBlogItem(BlogItem item, String text)
+ throws HibernateException {
+
+ item.setText(text);
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ session.update(item);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public void updateBlogItem(Long itemid, String text)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ try {
+ tx = session.beginTransaction();
+ BlogItem item = (BlogItem) session.load(BlogItem.class, itemid);
+ item.setText(text);
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ public List listAllBlogNamesAndItemCounts(int max)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "select blog.id, blog.name, count(blogItem) " +
+ "from Blog as blog " +
+ "left outer join blog.items as blogItem " +
+ "group by blog.name, blog.id " +
+ "order by max(blogItem.datetime)"
+ );
+ q.setMaxResults(max);
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+
+ public Blog getBlogAndAllItems(Long blogid)
+ throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ Blog blog = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "left outer join fetch blog.items " +
+ "where blog.id = :blogid"
+ );
+ q.setParameter("blogid", blogid);
+ blog = (Blog) q.uniqueResult();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return blog;
+ }
+
+ public List listBlogsAndRecentItems() throws HibernateException {
+
+ Session session = _sessions.openSession();
+ Transaction tx = null;
+ List result = null;
+ try {
+ tx = session.beginTransaction();
+ Query q = session.createQuery(
+ "from Blog as blog " +
+ "inner join blog.items as blogItem " +
+ "where blogItem.datetime > :minDate"
+ );
+
+ Calendar cal = Calendar.getInstance();
+ cal.roll(Calendar.MONTH, false);
+ q.setCalendar("minDate", cal);
+
+ result = q.list();
+ tx.commit();
+ }
+ catch (HibernateException he) {
+ if (tx!=null) tx.rollback();
+ throw he;
+ }
+ finally {
+ session.close();
+ }
+ return result;
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/filters.xml (from
rev 14070, core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/filters.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/filters.xml
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/content/filters.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="filters">
+ <title>Filtrer les donn�es</title>
+
+ <para>
+ Hibernate3 fournit une nouvelle approche innovatrice pour g�rer des donn�es
+ avec des r�gles de "visibilit�". Un <emphasis>filtre
Hibernate</emphasis> est un filtre
+ global, nomm�, param�tr� qui peut �tre activ� ou d�sactiv� pour une session
Hibernate
+ particuli�re.
+ </para>
+
+ <sect1 id="objectstate-filters">
+ <title>Filtres Hibernate</title>
+
+ <para>
+ Hibernate3 ajoute la capacit� de pr�d�finir des crit�res de filtre et
d'attacher ces
+ filtres � une classe ou � une collection. Un crit�re de filtre est la facult�
de d�finir
+ une clause de restriction tr�s similaire � l'attribut "where"
existant disponible sur
+ une classe et divers �l�ments d'une collection. Mis � part que ces
conditions de filtre
+ peuvent �tre param�tr�es. L'application peut alors prendre la d�cision �
l'ex�cution
+ si des filtres donn�s devraient �tre activ�s et quels devraient �tre leurs
param�tres.
+ Des filtres peuvent �tre utilis�s comme des vues de base de donn�es, mais
param�tr�es
+ dans l'application.
+ </para>
+
+ <para>
+ Afin d'utiliser des filtres, ils doivent d'abord �tre d�finis, puis
attach�s aux �l�ments
+ de mapping appropri�s. Pour d�finir un filtre, utilisez l'�l�ment
<literal><filter-def/></literal>
+ dans un �l�ment
<literal><hibernate-mapping/></literal> :
+ </para>
+
+ <programlisting><![CDATA[<filter-def name="myFilter">
+ <filter-param name="myFilterParam" type="string"/>
+</filter-def>]]></programlisting>
+
+ <para>
+ Puis, ce filtre peut �tre attach� � une classe :
+ </para>
+
+ <programlisting><![CDATA[<class name="myClass" ...>
+ ...
+ <filter name="myFilter" condition=":myFilterParam =
MY_FILTERED_COLUMN"/>
+</class>]]></programlisting>
+
+ <para>
+ ou � une collection :
+ </para>
+
+ <programlisting><![CDATA[<set ...>
+ <filter name="myFilter" condition=":myFilterParam =
MY_FILTERED_COLUMN"/>
+</set>]]></programlisting>
+
+ <para>
+ ou m�me aux deux (ou � plusieurs de chaque) en m�me temps.
+ </para>
+
+ <para>
+ Les m�thodes sur <literal>Session</literal> sont :
<literal>enableFilter(String filterName)</literal>,
+ <literal>getEnabledFilter(String filterName)</literal>, et
<literal>disableFilter(String filterName)</literal>.
+ Par d�faut, les filtres <emphasis>ne sont pas</emphasis> activ�s
pour une session donn�e ;
+ ils doivent �tre explicitement activ�s en appelant la m�thode
+ <literal>Session.enabledFilter()</literal>, laquelle retourne une
instance de l'interface
+ <literal>Filter</literal>. Utiliser le simple filtre d�fini
au-dessus ressemblerait � :
+ </para>
+
+
<programlisting><![CDATA[session.enableFilter("myFilter").setParameter("myFilterParam",
"some-value");]]></programlisting>
+
+ <para>
+ Notez que des m�thodes sur l'interface org.hibernate.Filter autorisent le
cha�nage de beaucoup
+ de m�thodes communes d'Hibernate.
+ </para>
+
+ <para>
+ Un exemple complet, utilisant des donn�es temporelles avec une structure de
date
+ d'enregistrement effectif :
+ </para>
+
+ <programlisting><![CDATA[<filter-def
name="effectiveDate">
+ <filter-param name="asOfDate" type="date"/>
+</filter-def>
+
+<class name="Employee" ...>
+...
+ <many-to-one name="department" column="dept_id"
class="Department"/>
+ <property name="effectiveStartDate" type="date"
column="eff_start_dt"/>
+ <property name="effectiveEndDate" type="date"
column="eff_end_dt"/>
+...
+ <!--
+ Note that this assumes non-terminal records have an eff_end_dt set to
+ a max db date for simplicity-sake
+ -->
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+</class>
+
+<class name="Department" ...>
+...
+ <set name="employees" lazy="true">
+ <key column="dept_id"/>
+ <one-to-many class="Employee"/>
+ <filter name="effectiveDate"
+ condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Puis, afin de s'assurer que vous pouvez toujours r�cup�rer les
enregistrements actuellement
+ effectifs, activez simplement le filtre sur la session avant de r�cup�rer des
donn�es des
+ employ�s :
+ </para>
+
+<programlisting><![CDATA[Session session = ...;
+session.enabledFilter("effectiveDate").setParameter("asOfDate", new
Date());
+List results = session.createQuery("from Employee as e where e.salary >
:targetSalary")
+ .setLong("targetSalary", new Long(1000000))
+ .list();
+]]></programlisting>
+
+ <para>
+ Dans le HQL ci-dessus, bien que nous ayons seulement mentionn� une contrainte
de
+ salaire sur les resultats, � cause du filtre activ�, la requ�te retournera
seulement
+ les employ�s actuellement actifs qui ont un salaire sup�rieur � un million de
dollars.
+ </para>
+
+ <para>
+ A noter : si vous pr�voyez d'utiliser des filtres avec des jointures
externes (soit
+ � travers HQL, soit par le chargement) faites attention � la direction de
l'expression
+ de condition. Il est plus s�r de la positionner pour les jointures externes �
gauche ;
+ en g�n�ral, placez le param�tre d'abord, suivi du(des) nom(s) de colonne
apr�s l'op�rateur.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Copied:
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/inheritance_mapping.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/inheritance_mapping.xml)
===================================================================
---
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/inheritance_mapping.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/inheritance_mapping.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,483 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="inheritance">
+ <title>Mapping d'h�ritage de classe</title>
+
+ <sect1 id="inheritance-strategies" revision="3">
+ <title>Les trois strat�gies</title>
+
+ <para>
+ Hibernate supporte les trois strat�gies d'h�ritage de base :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ une table par hi�rarchie de classe (table per class hierarchy)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ une table par classe fille (table per subclass)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ une table par classe concr�te (table per concrete class)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate supporte en plus une quatri�mestrat�gie, l�g�rement diff�rente, qui
supporte le polymorphisme :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ le polymorphisme implicite
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Il est possible d'utiliser diff�rentes strat�gies de mapping pour
diff�rentes branches d'une m�me
+ hi�rarchie d'h�ritage, et alors d'employer le polymorphisme implicite
pour r�aliser le
+ polymorphisme � travers toute la hi�rarchie. Pourtant, Hibernate ne supporte
pas de m�langer
+ des mappings <literal><subclass></literal> et
+ <literal><joined-subclass></literal> et
<literal><union-subclass></literal>
+ pour le m�me �l�ment <literal><class></literal>
racine.
+ Il est possible de m�langer ensemble les strat�gies d'une table par
hi�rarchie et d'une
+ table par sous-classe, pour le m�me �l�ment
<literal><class></literal>, en combinant
+ les �l�ments <literal><subclass></literal> et
<literal><join></literal> (voir dessous).
+ </para>
+
+ <para>
+ Il est possible de d�finir des mappings de
<literal>subclass</literal>, <literal>union-subclass</literal>,
+ et <literal>joined-subclass</literal> dans des documents de
mapping s�par�s, directement sous
+ <literal>hibernate-mapping</literal>. Ceci vous permet
d'�tendre une hi�rarchie de classe juste en
+ ajoutant un nouveau fichier de mapping. Vous devez sp�cifier un attribut
<literal>extends</literal>
+ dans le mapping de la sous-classe, en nommant une super-classe pr�c�demment
mapp�e. Note :
+ pr�c�demment cette foncionnalit� rendait l'ordre des documents de mapping
important. Depuis
+ Hibernate3, l'ordre des fichier de mapping n'importe plus lors de
l'utilisation du mot-clef "extends".
+ L'ordre � l'int�rieur d'un simple fichier de mapping impose
encore de d�finir les classes m�res
+ avant les classes filles.
+ </para>
+
+ <programlisting><![CDATA[
+ <hibernate-mapping>
+ <subclass name="DomesticCat" extends="Cat"
discriminator-value="D">
+ <property name="name" type="string"/>
+ </subclass>
+ </hibernate-mapping>]]></programlisting>
+
+
+ <sect2 id="inheritance-tableperclass" >
+ <title>Une table par hi�rarchie de classe</title>
+
+ <para>
+ Supposons que nous ayons une interface
<literal>Payment</literal>, impl�ment�e
+ par <literal>CreditCardPayment</literal>,
<literal>CashPayment</literal>,
+ <literal>ChequePayment</literal>. La strat�gie une table par
hi�rarchie serait :
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment"
table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment"
discriminator-value="CREDIT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment"
discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ Une seule table est requise. Une grande limitation de cette
+ strat�gie est que les colonnes d�clar�es par les classes filles, telles que
<literal>CCTYPE</literal>,
+ ne peuvent avoir de contrainte <literal>NOT NULL</literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass">
+ <title>Une table par classe fille</title>
+
+ <para>
+ La strat�gie une table par classe fille serait :
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment"
table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <joined-subclass name="CreditCardPayment"
table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment"
table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ Quatre tables sont requises. Les trois tables des classes filles ont
+ une cl� primaire associ�e � la table classe m�re (le mod�le relationnel
+ est une association un-vers-un).
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tablepersubclass-discriminator"
revision="2">
+ <title>Une table par classe fille, en utilisant un
discriminant</title>
+
+ <para>
+ Notez que l'impl�mentation Hibernate de la strat�gie un table par
+ classe fille ne n�cessite pas de colonne discriminante dans la table
+ classe m�re. D'autres impl�mentations de mappers Objet/Relationnel
utilisent
+ une autre impl�mentation de la strat�gie une table par classe fille qui
n�cessite
+ une colonne de type discriminant dans la table de la classe m�re.
L'approche
+ prise par Hibernate est plus difficile � impl�menter mais plus correcte
+ d'une point de vue relationnel. Si vous aimeriez utiliser
+ une colonne discriminante avec la strat�gie d'une table par classe fille,
vous pourriez combiner
+ l'utilisation de <literal><subclass></literal>
et
+ <literal><join></literal>, comme suit :
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment"
table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment"
discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ <join table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="ChequePayment"
discriminator-value="CHEQUE">
+ <join table="CHEQUE_PAYMENT" fetch="select">
+ <key column="PAYMENT_ID"/>
+ ...
+ </join>
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ La d�claration optionnelle
<literal>fetch="select"</literal> indique � Hibernate
+ de ne pas r�cup�rer les donn�es de la classe fille
<literal>ChequePayment</literal> par une jointure externe lors des requ�tes
sur la classe m�re.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-mixing-tableperclass-tablepersubclass">
+ <title>M�lange d'une table par hi�rarchie de classe avec une table
par classe fille</title>
+
+ <para>
+ Vous pouvez m�me m�langer les strat�gies d'une table par hi�rarchie de
classe et d'une table par classe fille en utilisant cette approche :
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment"
table="PAYMENT">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="PAYMENT_TYPE" type="string"/>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <subclass name="CreditCardPayment"
discriminator-value="CREDIT">
+ <join table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </join>
+ </subclass>
+ <subclass name="CashPayment" discriminator-value="CASH">
+ ...
+ </subclass>
+ <subclass name="ChequePayment"
discriminator-value="CHEQUE">
+ ...
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ Pour importe laquelle de ces strat�gies, une association polymorphique vers
la classe racine
+ <literal>Payment</literal> est mapp�e en utilisant
<literal><many-to-one></literal>.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="payment"
column="PAYMENT_ID" class="Payment"/>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcrete" revision="2">
+ <title>Une table par classe concr�te</title>
+
+ <para>
+ Il y a deux mani�res d'utiliser la strat�gie d'une table par classe
concr�te. La premi�re
+ est d'employer
<literal><union-subclass></literal>.
+ </para>
+
+ <programlisting><![CDATA[<class name="Payment">
+ <id name="id" type="long" column="PAYMENT_ID">
+ <generator class="sequence"/>
+ </id>
+ <property name="amount" column="AMOUNT"/>
+ ...
+ <union-subclass name="CreditCardPayment"
table="CREDIT_PAYMENT">
+ <property name="creditCardType" column="CCTYPE"/>
+ ...
+ </union-subclass>
+ <union-subclass name="CashPayment" table="CASH_PAYMENT">
+ ...
+ </union-subclass>
+ <union-subclass name="ChequePayment"
table="CHEQUE_PAYMENT">
+ ...
+ </union-subclass>
+</class>]]></programlisting>
+
+ <para>
+ Trois tables sont n�cessaires pour les classes filles. Chaque table d�finit
des colonnes
+ pour toutes les propri�t�s de la classe, incluant les propri�t�s h�rit��s.
+ </para>
+
+ <para>
+ La limitation de cette approche est que si une propri�t� est mapp�e sur la
classe m�re, le nom
+ de la colonne doit �tre le m�me pour toutes les classes filles. (Nous
pourrions �tre plus souple
+ dans une future version d'Hibernate).
+ La strat�gie du g�n�rateur d'identifiant n'est pas permise dans
l'h�ritage de classes filles par
+ union, en effet la valeur (NdT : seed) de la clef primaire
+ doit �tre partag�e par toutes les classes filles "union" d'une
hi�rarchie.
+ </para>
+
+ <para>
+ Si votre classe m�re est abstraite, mappez la avec
<literal>abstract="true"</literal>.
+ Bien s�r, si elle n'est pas abstraite, une table suppl�mentaire (par
d�faut,
+ <literal>PAYMENT</literal> dans l'exemple ci-dessus) est
requise pour contenir des instances
+ de la classe m�re.
+ </para>
+
+ </sect2>
+
+ <sect2 id="inheritance-tableperconcreate-polymorphism">
+ <title>Une table par classe concr�te, en utilisant le polymorphisme
implicite</title>
+
+ <para>
+ Une approche alternative est l'emploi du polymorphisme implicite :
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment"
table="CREDIT_PAYMENT">
+ <id name="id" type="long"
column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+</class>
+
+<class name="CashPayment" table="CASH_PAYMENT">
+ <id name="id" type="long"
column="CASH_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+</class>
+
+<class name="ChequePayment" table="CHEQUE_PAYMENT">
+ <id name="id" type="long"
column="CHEQUE_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+</class>]]></programlisting>
+
+ <para>
+ Notez que nulle part nous ne mentionnons l'interface
<literal>Payment</literal> explicitement.
+ Notez aussi que des propri�t�s de <literal>Payment</literal> sont
mapp�es dans
+ chaque classe fille. Si vous voulez �viter des duplications, consid�rez
l'utilisation des
+ entit�s XML (cf. <literal>[ <!ENTITY allproperties SYSTEM
"allproperties.xml"> ]</literal>
+ dans la d�claration du <literal>DOCTYPE</literal> et
<literal>&allproperties;</literal> dans le mapping).
+ </para>
+
+ <para>
+ L'inconv�nient de cette approche est qu'Hibernate ne g�n�re pas
d'<literal>UNION</literal>s SQL
+ lors de l'ex�cution des requ�tes polymorphiques.
+ </para>
+
+ <para>
+ Pour cette strat�gie de mapping, une association polymorphique pour
<literal>Payment</literal>
+ est habituellement mapp�e en utilisant
<literal><any></literal>.
+ </para>
+
+ <programlisting><![CDATA[<any name="payment"
meta-type="string" id-type="long">
+ <meta-value value="CREDIT" class="CreditCardPayment"/>
+ <meta-value value="CASH" class="CashPayment"/>
+ <meta-value value="CHEQUE" class="ChequePayment"/>
+ <column name="PAYMENT_CLASS"/>
+ <column name="PAYMENT_ID"/>
+</any>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="inheritace-mixingpolymorphism">
+ <title>M�lange du polymorphisme implicite avec d'autres mappings
d'h�ritage</title>
+
+ <para>
+ Il y a une chose suppl�mentaire � noter � propos de ce mapping. Puisque les
classes filles sont
+ chacune mapp�es avec leur propre �l�ment
<literal><class></literal> (et puisque
+ <literal>Payment</literal> est juste une interface), chaque
classe fille pourrait
+ facilement faire partie d'une autre hi�rarchie
+ d'h�ritage ! (Et vous pouvez encore faire des requ�tes polymorphiques
pour l'interface <literal>Payment</literal>).
+ </para>
+
+ <programlisting><![CDATA[<class name="CreditCardPayment"
table="CREDIT_PAYMENT">
+ <id name="id" type="long"
column="CREDIT_PAYMENT_ID">
+ <generator class="native"/>
+ </id>
+ <discriminator column="CREDIT_CARD" type="string"/>
+ <property name="amount" column="CREDIT_AMOUNT"/>
+ ...
+ <subclass name="MasterCardPayment"
discriminator-value="MDC"/>
+ <subclass name="VisaPayment" discriminator-value="VISA"/>
+</class>
+
+<class name="NonelectronicTransaction"
table="NONELECTRONIC_TXN">
+ <id name="id" type="long" column="TXN_ID">
+ <generator class="native"/>
+ </id>
+ ...
+ <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CASH_AMOUNT"/>
+ ...
+ </joined-subclass>
+ <joined-subclass name="ChequePayment"
table="CHEQUE_PAYMENT">
+ <key column="PAYMENT_ID"/>
+ <property name="amount" column="CHEQUE_AMOUNT"/>
+ ...
+ </joined-subclass>
+</class>]]></programlisting>
+
+ <para>
+ Encore une fois, nous ne mentionnons pas explicitement
<literal>Payment</literal>.
+ Si nous ex�cutons une requ�te sur l'interface
<literal>Payment</literal> - par
+ exemple, <literal>from Payment</literal> - Hibernate retournera
+ automatiquement les instances de
<literal>CreditCardPayment</literal>
+ (et ses classes filles puisqu'elles impl�mentent aussi
<literal>Payment</literal>),
+ <literal>CashPayment</literal> et
<literal>ChequePayment</literal> mais pas
+ les instances de <literal>NonelectronicTransaction</literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="inheritance-limitations">
+ <title>Limitations</title>
+
+ <para>
+ Il y a certaines limitations � l'approche du "polymorphisme
implicite"
+ pour la strat�gie de mapping d'une table par classe concr�te.
+ Il y a plut�t moins de limitations restrictives aux mappings
<literal><union-subclass></literal>.
+ </para>
+
+ <para>
+ La table suivante montre les limitations des mappings d'une table par
classe concr�te, et du polymorphisme implicite, dans Hibernate.
+ </para>
+
+ <table frame="topbot">
+ <title>Caract�ristiques du mapping d'h�ritage</title>
+ <tgroup cols='8' align='left' colsep='1'
rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <colspec colname='c6' colwidth="1*"/>
+ <colspec colname='c7' colwidth="1*"/>
+ <colspec colname='c8' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Strat�gie d'h�ritage</entry>
+ <entry>many-to-one polymorphique</entry>
+ <entry>one-to-one polymorphique</entry>
+ <entry>one-to-many polymorphique</entry>
+ <entry>many-to-many polymorphique</entry>
+ <entry><literal>load()/get()</literal>
polymorphique</entry>
+ <entry>Requ�tes polymorphiques</entry>
+ <entry>Jointures polymorphiques</entry>
+ <entry>R�cup�ration par jointure externe</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>une table par hi�rarchie de classe</entry>
+
<entry><literal><many-to-one></literal></entry>
+
<entry><literal><one-to-one></literal></entry>
+
<entry><literal><one-to-many></literal></entry>
+
<entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class,
id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment
p</literal></entry>
+ <entry><emphasis>support�e</emphasis></entry>
+ </row>
+ <row>
+ <entry>une table par classe fille</entry>
+
<entry><literal><many-to-one></literal></entry>
+
<entry><literal><one-to-one></literal></entry>
+
<entry><literal><one-to-many></literal></entry>
+
<entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class,
id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment
p</literal></entry>
+ <entry><emphasis>support�e</emphasis></entry>
+ </row>
+ <row>
+ <entry>une table par classe concr�te
(union-subclass)</entry>
+
<entry><literal><many-to-one></literal></entry>
+
<entry><literal><one-to-one></literal></entry>
+ <entry><literal><one-to-many></literal>
(pour <literal>inverse="true"</literal> seulement)</entry>
+
<entry><literal><many-to-many></literal></entry>
+ <entry><literal>s.get(Payment.class,
id)</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><literal>from Order o join o.payment
p</literal></entry>
+ <entry><emphasis>support�e</emphasis></entry>
+ </row>
+ <row>
+ <entry>une table par classe concr�te (polymorphisme
implicite)</entry>
+
<entry><literal><any></literal></entry>
+ <entry><emphasis>non support�</emphasis></entry>
+ <entry><emphasis>non support�</emphasis></entry>
+
<entry><literal><many-to-any></literal></entry>
+ <entry><literal>s.createCriteria(Payment.class).add(
Restrictions.idEq(id) ).uniqueResult()</literal></entry>
+ <entry><literal>from Payment p</literal></entry>
+ <entry><emphasis>non
support�es</emphasis></entry>
+ <entry><emphasis>non
support�e</emphasis></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/performance.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/performance.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/performance.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/performance.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,1451 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="performance">
+ <title>Am�liorer les performances</title>
+
+ <sect1 id="performance-fetching" revision="2">
+ <title>Strat�gies de chargement</title>
+
+ <para>
+ Une <emphasis>strat�gie de chargement</emphasis> est une
strat�gie qu'Hibernate va
+ utiliser pour r�cup�rer des objets associ�s si l'application � besoin de
naviguer �
+ travers une association.
+ Les strat�gies de chargement peuvent �tre d�clar�es dans les m�ta-donn�es de
l'outil
+ de mapping objet relationnel ou surcharg�es par une requ�te de type HQL ou
<literal>Criteria</literal>
+ particuli�re.
+ </para>
+
+ <para>
+ Hibernate3 d�finit les strat�gies de chargement suivantes :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Chargement par jointure</emphasis> - Hibernate
r�cup�re
+ l'instance associ�e ou la collection dans un m�me
<literal>SELECT</literal>,
+ en utilisant un <literal>OUTER JOIN</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Chargement par select</emphasis> - Un second
<literal>SELECT</literal>
+ est utilis� pour r�cup�rer l'instance associ�e ou la collection.
A moins
+ que vous ne d�sactiviez explicitement le chargement tardif en
sp�cifiant
+ <literal>lazy="false"</literal>, ce second
select ne sera ex�cut� que lorsque
+ vous acc�derez r�ellement � l'association.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Chargement par sous-select</emphasis> - Un
second <literal>SELECT</literal>
+ est utilis� pour r�cup�rer les associations pour toutes les entit�s
r�cup�r�es dans
+ une requ�te ou un chargement pr�alable. A moins
+ que vous ne d�sactiviez explicitement le chargement tardif en
sp�cifiant
+ <literal>lazy="false"</literal>, ce second
select ne sera ex�cut� que lorsque
+ vous acc�derez r�ellement � l'association.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Chargement par lot</emphasis> - Il s'agit
d'une strat�gie d'optimisation
+ pour le chargement par select - Hibernate r�cup�re un lot
+ d'instances ou de collections en un seul
<literal>SELECT</literal> en sp�cifiant
+ une liste de cl� primaire ou de cl� �trang�re.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate fait �galement la distinction entre :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Chargement imm�diat</emphasis> - Une
association, une collection ou
+ un attribut est charg� imm�diatement lorsque l'objet auquel
appartient cet
+ �l�ment est charg�.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Chargement tardif d'une
collection</emphasis> - Une collection est
+ charg�e lorque l'application invoque une m�thode sur cette
collection (il s'agit
+ du mode de chargement par d�faut pour les collections).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Chargement "super tardif" d'une
collection</emphasis> - les
+ �l�ments de la collection sont r�cup�r�s individuellement depuis la
base de donn�es
+ lorsque n�cessaire.
+ Hibernate essaie de ne pas charger toute la collection en m�moire
sauf si cela est
+ absolument n�cessaire (bien adapt� aux tr�s grandes collections).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Chargement par proxy</emphasis> - une
association vers un seul
+ objet est charg�e lorsqu'une m�thode autre que le getter sur
l'identifiant est
+ appel�e sur l'objet associ�.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Chargement "sans proxy"</emphasis> -
une association vers un seul objet
+ est charg�e lorsque l'on acc�de � cet objet. Par rapport au
chargement par proxy,
+ cette approche est moins tardif (l'association est quand m�me
charg�e m�me
+ si on n'acc�de qu'� l'identifiant) mais plus transparente
car il n'y a pas de proxy
+ visible dans l'application. Cette approche requiert une
instrumentation du bytecode
+ � la compilation et est rarement n�cessaire.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Chargement tardif des attributs</emphasis> - Un
attribut ou un
+ objet associ� seul est charg� lorsque l'on y acc�de. Cette
approche requiert
+ une instrumentation du bytecode � la compilation et est rarement
n�cessaire.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Nous avons ici deux notions orthogonales :
<emphasis>quand</emphasis> l'association est
+ charg�e et <emphasis>comment</emphasis> (quelle requ�te SQL est
utilis�e). Il ne faut
+ pas confondre les deux. Le mode de chargement est utilis� pour am�liorer les
performances.
+ On peut utiliser le mode tardif pour d�finir un contrat sur quelles donn�es
sont toujours
+ accessibles sur une instance d�tach�e d'une classe particuli�re.
+ </para>
+
+ <sect2 id="performance-fetching-lazy">
+ <title>Travailler avec des associations charg�es
tardivement</title>
+
+ <para>
+ Par d�faut, Hibernate3 utilise le chargement tardif par select pour les
collections
+ et le chargement tardif par proxy pour les associations vers un seul
objet.
+ Ces valeurs par d�faut sont valables pour la plupart des associations
dans la
+ plupart des applications.
+ </para>
+
+ <para>
+ <emphasis>Note :</emphasis> si vous d�finissez
+ <literal>hibernate.default_batch_fetch_size</literal>,
Hibernate va utiliser l'optimisation
+ du chargement par lot pour le chargement tardif (cette optimisation peut
aussi
+ �tre activ�e � un niveau de granularit� plus fin).
+ </para>
+
+ <para>
+ Cependant, le chargement tardif pose un probl�me qu'il faut
connaitre. L'acc�s �
+ une association d�finie comme "tardive", hors du contexte
d'une session hibernate
+ ouverte, va conduire � une exception. Par exemple :
+ </para>
+
+ <programlisting><![CDATA[s = sessions.openSession();
+Transaction tx = s.beginTransaction();
+
+User u = (User) s.createQuery("from User u where u.name=:userName")
+ .setString("userName", userName).uniqueResult();
+Map permissions = u.getPermissions();
+
+tx.commit();
+s.close();
+
+Integer accessLevel = (Integer) permissions.get("accounts"); //
Error!]]></programlisting>
+
+ <para>
+ Etant donn� que la collection des permissions n'a pas �t�
initialis�e
+ avant que la <literal>Session</literal> soit ferm�e, la
collection n'est
+ pas capable de se charger. <emphasis>Hibernate ne supporte pas le
chargement
+ tardif pour des objets d�tach�s</emphasis>. La solution � ce
probl�me est de
+ d�placer le code qui lit la collection avant le "commit" de la
transaction.
+ </para>
+
+ <para>
+ Une autre alternative est d'utiliser une collection ou une
association non
+ "tardive" en sp�cifiant
<literal>lazy="false"</literal> dans le mapping de
+ l'association.
+ Cependant il est pr�vu que le chargement tardif soit utilis� pour
quasiment
+ toutes les collections ou associations. Si vous d�finissez trop
d'associtions
+ non "tardives" dans votre mod�le objet, Hibernate va finir par
devoir charger
+ toute la base de donn�es en m�moire � chaque transaction !
+ </para>
+
+ <para>
+ D'un autre c�t�, on veut souvent choisir un chargement par jointure
(qui est par
+ d�faut non tardif) � la place du chargement par select dans une
transaction particuli�re.
+ Nous allons maintenant voir comment adapter les strat�gies de chargement.
Dans Hibernate3
+ les m�canismes pour choisir une strat�gie de chargement sont identiques
que
+ l'on ait une association vers un objet simple ou vers une
collection.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-custom" revision="4">
+ <title>Personnalisation des strat�gies de chargement</title>
+
+ <para>
+ Le chargement par select (mode par d�faut) est tr�s vuln�rable au
probl�me du
+ N+1 selects, du coup vous pouvez avoir envie d'activer le chargement
par jointure
+ dans les fichiers de mapping :
+ </para>
+
+ <programlisting><![CDATA[<set name="permissions"
+ fetch="join">
+ <key column="userId"/>
+ <one-to-many class="Permission"/>
+</set]]></programlisting>
+
+ <programlisting><![CDATA[<many-to-one name="mother"
class="Cat" fetch="join"/>]]></programlisting>
+
+ <para>
+ La strat�gie de chargement d�finie � l'aide du mot
<literal>fetch</literal> dans les fichiers
+ de mapping affecte :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ La r�cup�ration via <literal>get()</literal> ou
<literal>load()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ La r�cup�ration implicite lorsque l'on navigue � travers une
association
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Les requ�tes de type <literal>Criteria</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Les requ�tes HQL si l'on utilise le chargement par
<literal>subselect</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Quelle que soit la strat�gie de chargement que vous utilisez, la partie
du graphe
+ d'objets qui est d�finie comme non "tardive" sera charg�e
en m�moire. Cela peut
+ mener � l'ex�cution de plusieurs selects successifs pour une seule
requ�te HQL.
+ </para>
+
+ <para>
+ On n'utilise pas souvent les documents de mapping pour adapter le
chargement.
+ Au lieu de cela, on conserve le comportement par d�faut et on le
surcharge pour
+ une transaction particuli�re en utilisant <literal>left join
fetch</literal>
+ dans les requ�tes HQL. Cela indique � hibernate � Hibernate de charger
l'association
+ de mani�re agressive lors du premier select en utilisant une jointure
externe.
+ Dans l'API Criteria vous pouvez utiliser la m�thode
+ <literal>setFetchMode(FetchMode.JOIN)</literal>
+ </para>
+
+ <para>
+ Si vous ne vous sentez pas pr�t � modifier la strat�gie de chargement
utilis�
+ par <literal>get()</literal> ou
<literal>load()</literal>, vous pouvez juste
+ utiliser une requ�te de type <literal>Criteria</literal>
comme par exemple :
+ </para>
+
+ <programlisting><![CDATA[User user = (User)
session.createCriteria(User.class)
+ .setFetchMode("permissions", FetchMode.JOIN)
+ .add( Restrictions.idEq(userId) )
+ .uniqueResult();]]></programlisting>
+
+ <para>
+ (Il s'agit de l'�quivalent pour Hibernate de ce que d'autres
outils de mapping
+ appellent un "fetch plan" ou "plan de chargement")
+ </para>
+
+ <para>
+ Une autre mani�re compl�tement diff�rente d'�viter le probl�me des
N+1 selects
+ est d'utiliser le cache de second niveau.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-proxies" revision="2">
+ <title>Proxys pour des associations vers un seul objet</title>
+
+ <para>
+ Le chargement tardif des collections est impl�ment� par Hibernate en
utilisant
+ ses propres impl�mentations pour des collections persistantes. Si
l'on veut un
+ chargement tardif pour des associations vers un seul objet m�tier il faut
utiliser
+ un autre m�canisme. L'entit� qui est point�e par l'association
doit �tre masqu�e
+ derri�re un proxy. Hibernate impl�mente l'initialisation tardive des
proxys sur des
+ objets persistents via une mise � jour � chaud du bytecode (� l'aide
de l'excellente
+ librairie CGLIB).
+ </para>
+
+ <para>
+ Par d�faut, Hibernate g�n�re des proxys (au d�marrage) pour toutes les
classes
+ persistantes et les utilise pour activer le chargement tardif des
associations
+ <literal>many-to-one</literal> et
<literal>one-to-one</literal>.
+ </para>
+
+ <para>
+ Le fichier de mapping peut d�clarer une interface qui sera utilis�e par
le proxy
+ d'interfa�age pour cette classe � l'aide de l'attribut
<literal>proxy</literal>.
+ Par d�faut Hibernate utilises une sous classe de la classe persistante.
+ <emphasis>Il faut que les classes pour lesquelles on ajoute un
proxy impl�mentent
+ un constructeur par d�faut de visibilit� au moins package. Ce
constructeur est
+ recommand� pour toutes les classes persistantes !</emphasis>
+ </para>
+
+
+
+ <para>
+ Il y a quelques pr�cautions � prendre lorsque l'on �tend cette
approche � des classes
+ polymorphiques, exemple :
+ </para>
+
+ <programlisting><![CDATA[<class name="Cat"
proxy="Cat">
+ ......
+ <subclass name="DomesticCat" proxy="DomesticCat">
+ .....
+ </subclass>
+ </class>]]></programlisting>
+
+ <para>
+ Tout d'abord, les instances de <literal>Cat</literal> ne
pourront jamais �tre "cast�es"
+ en <literal>DomesticCat</literal>, m�me si l'instance sous
jacente est une instance
+ de <literal>DomesticCat</literal> :
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id);
// instancie un proxy (n'interroge pas la base de donn�es)
+if ( cat.isDomesticCat() ) { // interroge la base de donn�es pour
initialiser le proxy
+ DomesticCat dc = (DomesticCat) cat; // Erreur !
+ ....
+}]]></programlisting>
+
+ <para>
+ Deuxi�mement, il est possible de casser la notion
d'<literal>==</literal> des proxy.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id);
// instancie un proxy Cat
+DomesticCat dc =
+ (DomesticCat) session.load(DomesticCat.class, id); // acquiert un nouveau proxy
DomesticCat
+System.out.println(cat==dc); //
faux]]></programlisting>
+
+ <para>
+ Cette situation n'est pas si mauvaise qu'il n'y parait. M�me si
nous avons deux
+ r�f�rences � deux objets proxys diff�rents, l'instance de base sera quand
m�me le m�me objet :
+ </para>
+
+ <programlisting><![CDATA[cat.setWeight(11.0); // interroge la base de
donn�es pour initialiser le proxy
+System.out.println( dc.getWeight() ); // 11.0]]></programlisting>
+
+ <para>
+ Troisi�mement, vous ne pourrez pas utiliser un proxy CGLIB pour une classe
<literal>final</literal>
+ ou pour une classe contenant la moindre m�thode
<literal>final</literal>.
+ </para>
+
+ <para>
+ Enfin, si votre objet persistant obtient une ressource � l'instanciation
(par
+ example dans les initialiseurs ou dans le contructeur par d�faut), alors ces
ressources
+ seront aussi obtenues par le proxy. La classe proxy est vraiment une sous classe
de la classe
+ persistante.
+ </para>
+
+ <para>
+ Ces probl�mes sont tous dus aux limitations fondamentales du mod�le
d'h�ritage unique de Java.
+ Si vous souhaitez �viter ces probl�mes, vos classes persistantes doivent chacune
impl�menter
+ une interface qui d�clare ses m�thodes m�tier. Vous devriez alors sp�cifier ces
interfaces
+ dans le fichier de mapping :
+ </para>
+
+ <programlisting><![CDATA[<class name="CatImpl"
proxy="Cat">
+ ......
+ <subclass name="DomesticCatImpl" proxy="DomesticCat">
+ .....
+ </subclass>
+</class>]]></programlisting>
+
+ <para>
+ o� <literal>CatImpl</literal> impl�mente l'interface
<literal>Cat</literal> et <literal>DomesticCatImpl</literal>
+ impl�mente l'interface <literal>DomesticCat</literal>. Ainsi, des
proxys pour les instances de
+ <literal>Cat</literal> et <literal>DomesticCat</literal>
pourraient �tre retourn�es par <literal>load()</literal>
+ ou <literal>iterate()</literal> (Notez que
<literal>list()</literal> ne retourne g�n�ralement pas de proxy).
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) session.load(CatImpl.class,
catid);
+Iterator iter = session.createQuery("from CatImpl as cat where
cat.name='fritz'").iterate();
+Cat fritz = (Cat) iter.next();]]></programlisting>
+
+ <para>
+ Les relations sont aussi initialis�es tardivement. Ceci signifie que vous
+ devez d�clarer chaque propri�t� comme �tant de type
<literal>Cat</literal>,
+ et non <literal>CatImpl</literal>.
+ </para>
+
+ <para>
+ Certaines op�rations ne n�cessitent pas l'initialisation du proxy
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>equals()</literal>, si la classe persistante ne
surcharge pas
+ <literal>equals()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>hashCode()</literal>, si la classe persistante
ne surcharge pas
+ <literal>hashCode()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Le getter de l'identifiant
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate d�tectera les classes qui surchargent
<literal>equals()</literal> ou
+ <literal>hashCode()</literal>.
+ </para>
+
+ <para>
+ Eh choisissant <literal>lazy="no-proxy"</literal> au
lieu de <literal>lazy="proxy"</literal>
+ qui est la valeur par d�faut, il est possible d'�viter les probl�mes li�s
au transtypage.
+ Il faudra alors une instrumentation du bytecode � la compilation et toutes
les op�rations
+ r�sulterons imm�diatement en une initialisation du proxy.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-initialization"
revision="1">
+ <title>Initialisation des collections et des proxys</title>
+
+ <para>
+ Une exception de type
<literal>LazyInitializationException</literal> sera renvoy�e par hibernate
+ si une collection ou un proxy non initialis� est acc�d� en dehors de la
port�e de la <literal>Session</literal>,
+ e.g. lorsque l'entit� � laquelle appartient la collection ou qui a
une r�f�rence vers le proxy est
+ dans l'�tat "d�tach�e".
+ </para>
+
+ <para>
+ Parfois, nous devons nous assurer qu'un proxy ou une collection est
initialis�e avant de
+ fermer la <literal>Session</literal>. Bien s�r, nous pouvons
toujours forcer l'initialisation
+ en appelant par exemple <literal>cat.getSex()</literal> ou
<literal>cat.getKittens().size()</literal>.
+ Mais ceci n'est pas tr�s lisible pour les personnes parcourant le code et
n'est pas tr�s g�n�rique.
+ </para>
+
+ <para>
+ Les m�thodes statiques <literal>Hibernate.initialize()</literal>
et <literal>Hibernate.isInitialized()</literal>
+ fournissent � l'application un moyen de travailler avec des proxys ou des
collections initialis�s.
+ <literal>Hibernate.initialize(cat)</literal> forcera
l'initialisation d'un proxy de <literal>cat</literal>,
+ si tant est que sa <literal>Session</literal> est ouverte.
<literal>Hibernate.initialize( cat.getKittens() )</literal>
+ a le m�me effet sur la collection kittens.
+ </para>
+
+ <para>
+ Une autre option est de conserver la
<literal>Session</literal> ouverte jusqu'�
+ ce que toutes les collections et tous les proxys aient �t� charg�s. Dans
certaines
+ architectures applicatives, particuli�rement celles ou le code
d'acc�s aux donn�es
+ via hiberante et le code qui utilise ces donn�es sont dans des couches
applicatives
+ diff�rentes ou des processus physiques diff�rents, il peut devenir
probl�matique
+ de garantir que la <literal>Session</literal> est ouverte
lorsqu'une collection
+ est initialis�e. Il y a deux moyens de traiter ce probl�me :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Dans une application web, un filtre de servlet peut �tre utilis�
pour
+ fermer la <literal>Session</literal> uniquement
lorsque la requ�te
+ a �t� enti�rement trait�e, lorsque le rendu de la vue est fini
+ (il s'agit du pattern <emphasis>Open Session in
View</emphasis>).
+ Bien s�r, cela demande plus d'attention � la bonne gestion
des exceptions
+ de l'application. Il est d'une importance vitale que la
<literal>Session</literal>
+ soit ferm�e et la transaction termin�e avant que l'on rende
la main � l'utilisateur
+ m�me si une exception survient durant le traitement de la vue.
+ Voir le wiki Hibernate pour des exemples sur le pattern
+ "Open Session in View".
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Dans une application avec une couche m�tier s�par�e, la couche
contenant
+ la logique m�tier doit "pr�parer" toutes les
collections qui seront
+ n�cessaires � la couche web avant de retourner les donn�es. Cela
signifie
+ que la couche m�tier doit charger toutes les donn�es et retourner
toutes
+ les donn�es d�j� initialis�es � la couche de pr�sentation/web
pour un
+ cas d'utilisation donn�. En g�n�ral l'application appelle
la m�thode
+ <literal>Hibernate.initialize()</literal> pour chaque
collection n�cessaire
+ dans la couche web (cet appel doit �tre fait avant la fermeture
de la session)
+ ou bien r�cup�re les collections de mani�re agressive �
l'aide d'une requ�te
+ HQL avec une clause <literal>FETCH</literal> ou �
l'aide du mode
+ <literal>FetchMode.JOIN</literal> pour une requ�te de
type <literal>Criteria</literal>.
+ Cela est en g�n�ral plus facile si vous utilisez le pattern
<emphasis>Command</emphasis>
+ plut�t que <emphasis>Session Facade</emphasis>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Vous pouvez �galement attacher � une
<literal>Session</literal> un objet charg�
+ au pr�alable � l'aide des m�thodes
<literal>merge()</literal> ou <literal>lock()</literal>
+ avant d'acc�der aux collections (ou aux proxys) non
initialis�s. Non, Hibernate ne
+ fait pas, et ne doit pas faire, cela automatiquement car cela
pourrait introduire
+ une s�mantique transactionnelle ad hoc.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Parfois, vous ne voulez pas initialiser une grande collection mais vous
avez quand m�me
+ besoin d'informations sur elle (comme sa taille) ou un sous ensemble
de ses donn�es
+ </para>
+
+ <para>
+ Vous pouvez utiliser un filtre de collection pour r�cup�rer sa taille
sans l'initialiser :
+ </para>
+
+ <programlisting><![CDATA[( (Integer) s.createFilter( collection,
"select count(*)" ).list().get(0) ).intValue()]]></programlisting>
+
+ <para>
+ La m�thode <literal>createFilter()</literal> est �galement
utilis�e pour r�cup�rer
+ de mani�re efficace des sous ensembles d'une collection sans avoir
besoin de l'initialiser
+ dans son ensemble.
+ </para>
+
+ <programlisting><![CDATA[s.createFilter( lazyCollection,
"").setFirstResult(0).setMaxResults(10).list();]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="performance-fetching-batch">
+ <title>Utiliser le chargement par lot</title>
+
+ <para>
+ Pour am�liorer les performances, Hibernate peut utiliser le chargement par
lot
+ ce qui veut dire qu'Hibernate peut charger plusieurs proxys (ou
collections) non initialis�s en une seule
+ requ�te lorsque l'on acc�de � l'un de ces proxys. Le chargement par
lot est une optimisation
+ intimement li�e � la strat�gie de chargement tardif par select. Il y a deux
moyens d'activer le
+ chargement par lot : au niveau de la classe et au niveau de la collection.
+ </para>
+
+ <para>
+ Le chargement par lot pour les classes/entit�s est plus simple � comprendre.
Imaginez que vous ayez la
+ situation suivante � l'ex�cution : vous avez 25 instances de
<literal>Cat</literal>
+ charg�es dans une <literal>Session</literal>, chaque
<literal>Cat</literal> a une r�f�rence
+ � son <literal>owner</literal>, une
<literal>Person</literal>.
+ La classe <literal>Person</literal> est mapp�e avec un proxy,
<literal>lazy="true"</literal>.
+ Si vous it�rez sur tous les cats et appelez
<literal>getOwner()</literal> sur chacun d'eux,
+ Hibernate ex�cutera par d�faut 25 <literal>SELECT</literal>, pour
charger les owners
+ (initialiser le proxy). Vous pouvez param�trer ce comportement en sp�cifiant
une
+ <literal>batch-size</literal> (taille du lot) dans le mapping de
<literal>Person</literal> :
+ </para>
+
+ <programlisting><![CDATA[<class name="Person"
batch-size="10">...</class>]]></programlisting>
+
+ <para>
+ Hibernate ex�cutera d�sormais trois requ�tes, en chargeant respectivement 10,
+ 10, et 5 entit�s.
+ </para>
+
+ <para>
+ Vous pouvez aussi activer le chargement par lot pour les collections. Par
exemple,
+ si chaque <literal>Person</literal> a une collection charg�e
tardivement de
+ <literal>Cat</literal>s, et que 10 personnes sont actuellement
charg�es dans la
+ <literal>Session</literal>, it�rer sur toutes les persons
g�n�rera 10 <literal>SELECT</literal>s,
+ un pour chaque appel de <literal>getCats()</literal>. Si vous
activez le chargement par lot pour la
+ collection <literal>cats</literal> dans le mapping de
<literal>Person</literal>, Hibernate pourra
+ pr�charger les collections :
+ </para>
+
+ <programlisting><![CDATA[<class name="Person">
+ <set name="cats" batch-size="3">
+ ...
+ </set>
+</class>]]></programlisting>
+
+ <para>
+ Avec une taille de lot (<literal>batch-size</literal>) de 3,
Hibernate chargera
+ respectivement 3, 3, 3, et 1 collections en quatre
<literal>SELECT</literal>s.
+ Encore une fois, la valeur de l'attribut d�pend du nombre de collections
+ non initialis�es dans une <literal>Session</literal> particuli�re.
+ </para>
+
+ <para>
+ Le chargement par lot de collections est particuli�rement utile si vous avez
des
+ arborescenses r�cursives d'�l�ments (typiquement, le sch�ma facture de
+ mat�riels). (Bien qu'un <emphasis>sous ensemble</emphasis> ou un
+ <emphasis>chemin mat�rialis�</emphasis> est sans doute une meilleure
option pour
+ des arbres principalement en lecture.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-fetching-subselect">
+ <title>Utilisation du chargement par sous select</title>
+
+ <para>
+ Si une collection ou un proxy vers un objet doit �tre charg�, Hibernate
va tous les
+ charger en r�-ex�cutant la requ�te orignial dans un sous select. Cela
fonctionne de la
+ m�me mani�re que le chargement par lot sans la possibilit� de fragmenter
le chargement.
+ </para>
+
+ <!-- TODO: Write more about this -->
+
+ </sect2>
+
+ <sect2 id="performance-fetching-lazyproperties">
+ <title>Utiliser le chargement tardif des propri�t�s</title>
+
+ <para>
+ Hibernate3 supporte le chargement tardif de propri�t�s individuelles. La
technique
+ d'optimisation est �galement connue sous le nom de
<emphasis>fetch groups</emphasis> (groupes
+ de chargement). Il faut noter qu'il s'agit principalement
d'une fonctionnalit� marketing
+ car en pratique l'optimisation de la lecture d'un enregistrement
est beaucoup plus importante
+ que l'optimisation de la lecture d'une colonne. Cependant, la
restriction du chargement �
+ certaines colonnes peut �tre pratique dans des cas extr�mes, lorsque des
tables "legacy"
+ poss�dent des centaines de colonnes et que le mod�le de donn�es ne peut
pas �tre am�lior�.
+ </para>
+
+ <para>
+ Pour activer le chargement tardif d'une propri�t�, il faut mettre
l'attribut <literal>lazy</literal>
+ sur une propri�t� particuli�re du mapping :
+ </para>
+
+ <programlisting><![CDATA[<class name="Document">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name" not-null="true"
length="50"/>
+ <property name="summary" not-null="true"
length="200" lazy="true"/>
+ <property name="text" not-null="true" length="2000"
lazy="true"/>
+</class>]]></programlisting>
+
+ <para>
+ Le chargement tardif des propri�t�s requiert une instrumentation du
bytecode lors de la
+ compilation ! Si les classes persistantes ne sont pas instrument�es,
Hibernate ignorera de
+ mani�re silencieuse le mode tardif et retombera dans le mode de
chargement imm�diat.
+ </para>
+
+ <para>
+ Pour l'instrumentation du bytecode vous pouvez utiliser la t�che Ant
suivante :
+ </para>
+
+ <programlisting><![CDATA[<target name="instrument"
depends="compile">
+ <taskdef name="instrument"
classname="org.hibernate.tool.instrument.InstrumentTask">
+ <classpath path="${jar.path}"/>
+ <classpath path="${classes.dir}"/>
+ <classpath refid="lib.class.path"/>
+ </taskdef>
+
+ <instrument verbose="true">
+ <fileset dir="${testclasses.dir}/org/hibernate/auction/model">
+ <include name="*.class"/>
+ </fileset>
+ </instrument>
+</target>]]></programlisting>
+
+ <para>
+ Une autre fa�on (meilleure ?) pour �viter de lire plus de colonnes que
+ n�cessaire au moins pour des transactions en lecture seule est
d'utiliser
+ les fonctionnalit�s de projection des requ�tes HQL ou Criteria. Cela
�vite
+ de devoir instrumenter le bytecode � la compilation et est certainement
une
+ solution pr�f�rable.
+ </para>
+
+ <para>
+ Vous pouvez forcer le mode de chargement agressif des propri�t�s en
utilisant
+ <literal>fetch all properties</literal> dans les requ�ts
HQL.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="performance-cache" revision="1">
+ <title>Le cache de second niveau</title>
+
+ <para>
+ Une <literal>Session</literal> Hibernate est un cache de niveau
transactionnel
+ des donn�es persistantes. Il est possible de configurer un cache de cluster ou de
JVM
+ (de niveau <literal>SessionFactory</literal> pour �tre exact) d�fini
classe par classe
+ et collection par collection. Vous pouvez m�me utiliser votr choix de cache
+ en impl�mentant le pourvoyeur (provider) associ�.
+ Faites attention, les caches ne sont jamais avertis des modifications faites
+ dans la base de donn�es par d'autres applications (ils peuvent cependant �tre
+ configur�s pour r�guli�rement expirer les donn�es en cache).
+ </para>
+
+ <para>
+ Par d�faut, Hibernate utilise EHCache comme cache de niveau JVM (le support
+ de JCS est d�sormais d�pr�ci� et sera enlev� des futures versions
d'Hibernate).
+ Vous pouvez choisir une autre impl�mentation en sp�cifiant le nom de la classe
qui
+ impl�mente <literal>org.hibernate.cache.CacheProvider</literal> en
utilisant
+ la propri�t� <literal>hibernate.cache.provider_class</literal>.
+ </para>
+
+ <table frame="topbot" id="cacheproviders"
revision="1">
+ <title>Fournisseur de cache</title>
+ <tgroup cols='5' align='left' colsep='1'
rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="3*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Cache</entry>
+ <entry>Classe pourvoyeuse</entry>
+ <entry>Type</entry>
+ <entry>Support en Cluster</entry>
+ <entry>Cache de requ�tes support�</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable (ne pas utiliser en production)</entry>
+
<entry><literal>org.hibernate.cache.HashtableCacheProvider</literal></entry>
+ <entry>m�moire</entry>
+ <entry></entry>
+ <entry>oui</entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+
<entry><literal>org.hibernate.cache.EhCacheProvider</literal></entry>
+ <entry>m�moire, disque</entry>
+ <entry></entry>
+ <entry>oui</entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+
<entry><literal>org.hibernate.cache.OSCacheProvider</literal></entry>
+ <entry>m�moire, disque</entry>
+ <entry>oui (invalidation de cluster)</entry>
+ <entry>oui</entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+
<entry><literal>org.hibernate.cache.SwarmCacheProvider</literal></entry>
+ <entry>en cluster (multicast ip)</entry>
+ <entry>oui (invalidation de cluster)</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+
<entry><literal>org.hibernate.cache.TreeCacheProvider</literal></entry>
+ <entry>en cluster (multicast ip), transactionnel</entry>
+ <entry>oui (replication)</entry>
+ <entry>oui (horloge sync. n�cessaire)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="performance-cache-mapping" revision="2">
+ <title>Mapping de Cache</title>
+
+ <para>
+ L'�l�ment <literal><cache></literal>
d'une classe ou d'une collection �
+ la forme suivante :
+ </para>
+
+ <programlistingco>
+ <areaspec>
+ <area id="cache1" coords="2 70"/>
+ <area id="cache2" coords="3 70"/>
+ <area id="cache3" coords="4 70"/>
+ </areaspec>
+ <programlisting><![CDATA[<cache
+ usage="transactional|read-write|nonstrict-read-write|read-only"
+ region="RegionName"
+ include="all|non-lazy"
+/>]]></programlisting>
+ <calloutlist>
+ <callout arearefs="cache1">
+ <para>
+ <literal>usage</literal> (requis) sp�cifie la
strat�gie de cache :
+ <literal>transactionel</literal>,
+ <literal>lecture-�criture</literal>,
+ <literal>lecture-�criture non stricte</literal>
ou
+ <literal>lecture seule</literal>
+ </para>
+ </callout>
+ <callout arearefs="cache2">
+ <para>
+ <literal>region</literal> (optionnel, par d�faut
il s'agit du nom
+ de la classe ou du nom de role de la collection) sp�cifie le
nom de la
+ r�gion du cache de second niveau
+ </para>
+ </callout>
+ <callout arearefs="cache3">
+ <para>
+ <literal>include</literal> (optionnel, par d�faut
<literal>all</literal>)
+ <literal>non-lazy</literal> sp�cifie que les
propri�t�s des entit�s mapp�es avec
+ <literal>lazy="true"</literal> ne
doivent pas �tre mises en cache lorsque
+ le chargement tardif des attributs est activ�.
+ </para>
+ </callout>
+ </calloutlist>
+ </programlistingco>
+
+ <para>
+ Alternativement (voir pr�f�rentiellement), vous pouvez sp�cifier les
�l�ments
+ <literal><class-cache></literal> et
<literal><collection-cache></literal>
+ dans <literal>hibernate.cfg.xml</literal>.
+ </para>
+
+ <para>
+ L'attribut <literal>usage</literal> sp�cifie une
<emphasis>strat�gie de concurrence d'acc�s au cache</emphasis>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-readonly">
+ <title>Strategie : lecture seule</title>
+
+ <para>
+ Si votre application a besoin de lire mais ne modifie jamais les
instances d'une classe,
+ un cache <literal>read-only</literal> peut �tre utilis�. C'est la
strat�gie la plus simple
+ et la plus performante. Elle est m�me parfaitement s�re dans un cluster.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Immutable"
mutable="false">
+ <cache usage="read-only"/>
+ ....
+</class>]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="performance-cache-readwrite">
+ <title>Strat�gie : lecture/�criture</title>
+
+ <para>
+ Si l'application a besoin de mettre � jour des donn�es, un cache
<literal>read-write</literal> peut
+ �tre appropri�. Cette strat�gie ne devrait jamais �tre utilis�e si votre
application
+ n�cessite un niveau d'isolation transactionnelle s�rialisable. Si le cache
est utilis�
+ dans un environnement JTA, vous devez sp�cifier
+ <literal>hibernate.transaction.manager_lookup_class</literal>,
fournissant une strat�gie pour obtenir
+ le <literal>TransactionManager</literal> JTA. Dans d'autres
environnements, vous devriez vous assurer
+ que la transation est termin�e � l'appel de
<literal>Session.close()</literal>
+ ou <literal>Session.disconnect()</literal>. Si vous souhaitez
utiliser cette strat�gie
+ dans un cluster, vous devriez vous assurer que l'impl�mentation de cache
utilis�e supporte
+ le v�rrouillage. Ce que ne font <emphasis>pas</emphasis> les
pourvoyeurs caches fournis.
+ </para>
+
+ <programlisting><![CDATA[<class name="eg.Cat" ....
>
+ <cache usage="read-write"/>
+ ....
+ <set name="kittens" ... >
+ <cache usage="read-write"/>
+ ....
+ </set>
+</class>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-cache-nonstrict">
+ <title>Strat�gie : lecture/�criture non stricte</title>
+
+ <para>
+ Si l'application besoin de mettre � jour les donn�es de mani�re
occasionnelle
+ (qu'il est tr�s peu probable que deux transactions essaient de mettre � jour
le m�me
+ �l�ment simultan�ment) et qu'une isolation transactionnelle stricte n'est
pas n�cessaire,
+ un cache <literal>nonstrict-read-write</literal> peut �tre appropri�.
Si le cache est
+ utilis� dans un environnement JTA, vous devez sp�cifier
+ <literal>hibernate.transaction.manager_lookup_class</literal>. Dans
d'autres
+ environnements, vous devriez vous assurer que la transation est termin�e �
l'appel
+ de <literal>Session.close()</literal> ou
<literal>Session.disconnect()</literal>
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-cache-transactional">
+ <title>Strat�gie : transactionelle</title>
+
+ <para>
+ La strat�gie de cache <literal>transactional</literal>
supporte un cache
+ compl�tement transactionnel comme, par exemple, JBoss TreeCache. Un tel cache ne
+ peut �tre utilis� que dans un environnement JTA et vous devez sp�cifier
+ <literal>hibernate.transaction.manager_lookup_class</literal>.
+ </para>
+
+ </sect2>
+
+ <para>
+ Aucun des caches livr�s ne supporte toutes les strat�gies de concurrence. Le
tableau suivant montre
+ quels caches sont compatibles avec quelles strat�gies de concurrence.
+ </para>
+
+ <table frame="topbot">
+ <title>Strat�gie de concurrence du cache</title>
+ <tgroup cols='5' align='left' colsep='1'
rowsep='1'>
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="1*"/>
+ <colspec colname='c3' colwidth="1*"/>
+ <colspec colname='c4' colwidth="1*"/>
+ <colspec colname='c5' colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Cache</entry>
+ <entry>read-only (lecture seule)</entry>
+ <entry>nonstrict-read-write (lecture-�criture non
stricte)</entry>
+ <entry>read-write (lecture-�riture)</entry>
+ <entry>transactional (transactionnel)</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Hashtable (ne pas utilser en production)</entry>
+ <entry>oui</entry>
+ <entry>oui</entry>
+ <entry>oui</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>EHCache</entry>
+ <entry>oui</entry>
+ <entry>oui</entry>
+ <entry>oui</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>OSCache</entry>
+ <entry>oui</entry>
+ <entry>oui</entry>
+ <entry>oui</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>SwarmCache</entry>
+ <entry>oui</entry>
+ <entry>oui</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>JBoss TreeCache</entry>
+ <entry>oui</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>oui</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="performance-sessioncache" revision="2">
+ <title>G�rer les caches</title>
+
+ <para>
+ A chaque fois que vous passez un objet � la m�thode
<literal>save()</literal>,
+ <literal>update()</literal> ou
<literal>saveOrUpdate()</literal> et � chaque fois
+ que vous r�cup�rez un objet avec <literal>load()</literal>,
<literal>get()</literal>,
+ <literal>list()</literal>,
<literal>iterate()</literal> or <literal>scroll()</literal>,
+ cet objet est ajout� au cache interne de la
<literal>Session</literal>.
+ </para>
+ <para>
+ Lorsqu'il y a un appel � la m�thode
<literal>flush()</literal>, l'�tat de cet objet
+ va �tre synchronis� avec la base de donn�es. Si vous ne voulez pas que cette
synchronisation
+ ait lieu ou si vous traitez un grand nombre d'objets et que vous avez
besoin de g�rer
+ la m�moire de mani�re efficace, vous pouvez utiliser la m�thode
<literal>evict()</literal>
+ pour supprimer l'objet et ses collections d�pendantes du cache de la
session
+ </para>
+
+ <programlisting><![CDATA[ScrollableResult cats =
sess.createQuery("from Cat as cat").scroll(); //a huge result set
+while ( cats.next() ) {
+ Cat cat = (Cat) cats.get(0);
+ doSomethingWithACat(cat);
+ sess.evict(cat);
+}]]></programlisting>
+
+ <para>
+ La <literal>Session</literal> dispose aussi de la m�thode
<literal>contains()</literal> pour d�terminer
+ si une instance appartient au cache de la session.
+ </para>
+
+ <para>
+ Pour retirer tous les objets du cache session, appelez
<literal>Session.clear()</literal>
+ </para>
+
+ <para>
+ Pour le cache de second niveau, il existe des m�thodes d�finies dans
+ <literal>SessionFactory</literal> pour retirer des instances du
cache,
+ la classe enti�re, une instance de collection ou
+ le r�le entier d'une collection.
+ </para>
+
+ <programlisting><![CDATA[sessionFactory.evict(Cat.class, catId); //evict
a particular Cat
+sessionFactory.evict(Cat.class); //evict all Cats
+sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular
collection of kittens
+sessionFactory.evictCollection("Cat.kittens"); //evict all kitten
collections]]></programlisting>
+
+ <para>
+ Le <literal>CacheMode</literal> contr�le comme une session
particuli�re interragit avec le
+ cache de second niveau
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>CacheMode.NORMAL</literal> - lit et �crit les items dans
le cache de second niveau
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.GET</literal> - lit les items dans le cache de
second niveau mais ne
+ les �crit pas sauf dans le cache d'une mise � jour d'une donn�e
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.PUT</literal> - �crit les items dans le cache
de second niveau mais ne les
+ lit pas dans le cache de second niveau
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CacheMode.REFRESH</literal> - �crit les items dans le
cache de second niveau mais ne les
+ lit pas dans le cache de second niveau, outrepasse l'effet
de<literal>hibernate.cache.use_minimal_puts</literal>,
+ en for�ant un rafra�chissement du cache de second niveau pour chaque item lu
dans la base
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Pour parcourir le contenu du cache de second niveau ou la r�gion du cache
d�di�e au requ�tes, vous
+ pouvez utiliser l'API <literal>Statistics</literal>
+ API:
+ </para>
+
+ <programlisting><![CDATA[Map cacheEntries =
sessionFactory.getStatistics()
+ .getSecondLevelCacheStatistics(regionName)
+ .getEntries();]]></programlisting>
+
+ <para>
+ Vous devez pour cela activer les statistiques et optionnellement forcer
Hibernate � conserver les entr�es dans le
+ cache sous un format plus compr�hensible pour l'utilisateur :
+ </para>
+
+ <programlisting><![CDATA[hibernate.generate_statistics true
+hibernate.cache.use_structured_entries true]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="performance-querycache" revision="1">
+ <title>Le cache de requ�tes</title>
+
+ <para>
+ Les r�sultats d'une requ�te peuvent aussi �tre plac�s en cache. Ceci
n'est utile
+ que pour les requ�tes qui sont ex�cut�es avec les m�mes param�tres. Pour
utiliser
+ le cache de requ�tes, vous devez d'abord l'activer :
+ </para>
+
+ <programlisting><![CDATA[hibernate.cache.use_query_cache
true]]></programlisting>
+
+ <para>
+ Ce param�tre am�ne la cr�ation de deux nouvelles r�gions dans le cache, une qui
va conserver
+ le r�sultat des requ�tes mises en cache
(<literal>org.hibernate.cache.StandardQueryCache</literal>)
+ et l'autre qui va conserver l'horodatage des mises � jour les plus
r�centes effectu�es sur les
+ tables requ�tables
(<literal>org.hibernate.cache.UpdateTimestampsCache</literal>).
+ Il faut noter que le cache de requ�te ne conserve pas l'�tat des entit�s,
il met en cache
+ uniquement les valeurs de l'identifiant et les valeurs de types de base
(?). Le cache
+ de requ�te doit toujours �tre utilis� avec le cache de second niveau pour �tre
efficace.
+ </para>
+
+ <para>
+ La plupart des requ�tes ne retirent pas de b�n�fice pas du cache,
+ donc par d�faut les requ�tes ne sont pas mises en cache. Pour activer le cache,
+ appelez <literal>Query.setCacheable(true)</literal>.
+ Cet appel permet de v�rifier si les r�sultats sont en cache ou non, voire
+ d'ajouter ces r�sultats si la requ�te est ex�cut�e.
+ </para>
+
+ <para>
+ Si vous avez besoin de contr�ler finement les d�lais d'expiration du cache,
vous
+ pouvez sp�cifier une r�gion de cache nomm�e pour une requ�te particuli�re en
+ appelant <literal>Query.setCacheRegion()</literal>.
+ </para>
+
+ <programlisting><![CDATA[List blogs = sess.createQuery("from Blog
blog where blog.blogger = :blogger")
+ .setEntity("blogger", blogger)
+ .setMaxResults(15)
+ .setCacheable(true)
+ .setCacheRegion("frontpages")
+ .list();]]></programlisting>
+
+ <para>
+ Si une requ�te doit forcer le rafra�chissement de sa r�gion de cache, vous
devez
+ appeler <literal>Query.setCacheMode(CacheMode.REFRESH)</literal>.
C'est particuli�rement
+ utile lorsque les donn�es peuvent avoir �t� mises � jour par un processus
s�par� (e.g. elles
+ n'ont pas �t� modifi�es par Hibernate). Cela permet � l'application de
rafra�chir de
+ mani�re s�lective les r�sultats d'une requ�te particuli�re. Il s'agit
d'une alternative plus
+ efficace � l'�viction d'une r�gion du cache � l'aide de la m�thode
+ <literal>SessionFactory.evictQueries()</literal>.
+ </para>
+
+ </sect1>
+ <sect1 id="performance-collections">
+ <title>Comprendre les performances des Collections</title>
+
+ <para>
+ Nous avons d�j� pass� du temps � discuter des collections.
+ Dans cette section, nous allons traiter du comportement des
+ collections � l'ex�cution.
+ </para>
+
+ <sect2 id="performance-collections-taxonomy">
+ <title>Classification</title>
+
+ <para>Hibernate d�finit trois types de collections :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>les collections de valeurs</para>
+ </listitem>
+ <listitem>
+ <para>les associations un-vers-plusieurs</para>
+ </listitem>
+ <listitem>
+ <para>les associations plusieurs-vers-plusieurs</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Cette classification distingue les diff�rentes relations entre les
tables
+ et les cl�s �trang�res mais ne nous apprend rien de ce que nous devons savoir
+ sur le mod�le relationnel. Pour comprendre parfaitement la structure
relationnelle
+ et les caract�ristiques des performances, nous devons consid�rer la structure
+ de la cl� primaire qui est utilis�e par Hibernate pour mettre � jour ou
supprimer
+ les �l�ments des collections. Cel� nous am�ne aux classifications suivantes :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>collections index�es</para>
+ </listitem>
+ <listitem>
+ <para>sets</para>
+ </listitem>
+ <listitem>
+ <para>bags</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Toutes les collections index�es (maps, lists, arrays) ont une cl�
primaire constitu�e
+ des colonnes cl� (<literal><key></literal>) et
<literal><index></literal>.
+ Avec ce type de cl� primaire, la mise � jour de collection est en g�n�ral tr�s
performante - la cl�
+ primaire peut �tre index�es efficacement et un �l�ment particulier peut �tre
+ localis� efficacement lorsqu'Hibernate essaie de le mettre � jour ou de le
supprimer.
+ </para>
+
+ <para>
+ Les Sets ont une cl� primaire compos�e de
<literal><key></literal> et des
+ colonnes repr�sentant l'�l�ment. Elle est donc moins efficace pour
certains
+ types de collections d'�l�ments, en particulier les �l�ments
composites,
+ les textes volumineux ou les champs binaires ; la base de donn�es
+ peut ne pas �tre capable d'indexer aussi efficacement une cl�
primaire
+ aussi complexe. Cependant, pour les associations un-vers-plusieurs
+ ou plusieurs-vers-plusieurs, sp�cialement lorsque l'on utilise des
entit�s
+ ayant des identifiants techniques, il est probable que cela soit aussi
efficace
+ (note : si vous voulez que <literal>SchemaExport</literal>
cr�� effectivement
+ la cl� primaire d'un
<literal><set></literal> pour vous, vous devez
+ d�clarer toutes les colonnes avec
<literal>not-null="true"</literal>).
+ </para>
+
+ <para>
+ Le mapping � l'aide
d'<literal><idbag></literal> d�finit une cl�
+ de substitution ce qui leur permet d'�tre tr�s efficaces lors de la
+ mise � jour. En fait il s'agit du meilleur cas de mise � jour d'une
collection
+ </para>
+
+ <para>
+ Le pire cas intervient pour les Bags. Dans la mesure o� un bag permet
+ la duplications des �l�ments et n'a pas de colonne d'index, aucune
cl� primaire
+ ne peut �tre d�finie. Hibernate n'a aucun moyen de distinguer des
enregistrements
+ dupliqu�s. Hibernate r�sout ce probl�me en supprimant compl�tement les
+ enregistrements (via un simple <literal>DELETE</literal>), puis
en recr�ant
+ la collection chaque fois qu'elle change. Ce qui peut �tre tr�s
inefficace.
+ </para>
+
+ <para>
+ Notez que pour une relation un-vers-plusieurs, la "cl� primaire"
+ peut ne pas �tre la cl� primaire de la table en base de donn�es -
+ mais m�me dans ce cas, la classification ci-dessus reste utile
+ (Elle explique comment Hibernate "localise" chaque
enregistrement
+ de la collection).
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficientupdate">
+ <title>Les lists, les maps, les idbags et les sets sont les collections
les plus efficaces pour la mise � jour</title>
+
+ <para>
+ La discussion pr�c�dente montre clairement que les collections index�es
+ et (la plupart du temps) les sets, permettent de r�aliser le plus
efficacement
+ les op�rations d'ajout, de suppression ou de modification
d'�l�ments.
+ </para>
+
+ <para>
+ Il existe un autre avantage qu'ont les collections index�es sur les
Sets
+ dans le cadre d'une association plusieurs vers plusieurs ou
d'une collection de valeurs.
+ A cause de la structure inh�rente d'un
<literal>Set</literal>, Hibernate n'effectue jamais
+ d'<literal>UPDATE</literal> quand un enregistrement est
modifi�. Les modifications
+ apport�es � un <literal>Set</literal> se font via un
<literal>INSERT</literal> et <literal>DELETE</literal>
+ (de chaque enregistrement). Une fois de plus, ce cas ne s'applique
pas aux associations
+ un vers plusieurs.
+ </para>
+
+ <para>
+ Apr�s s'�tre rappel� que les tableaux ne peuvent pas �tre charg�s
tardivement,
+ nous pouvons conclure que les lists, les maps et les idbags sont les types
de collections
+ (non invers�es) les plus performants, avec les sets pas loin derri�res.
+ Les sets son le type de collection le plus courant dans les applications
Hibernate. Cela
+ est du au fait que la s�mantique des "set" est la plus naturelle
dans le mod�le
+ relationnel.
+ </para>
+
+ <para>
+ Cependant, dans des mod�les objet bien con�us avec Hibernate, on voit
souvent que
+ la plupart des collections sont en fait des associations
"un-vers-plusieurs" avec
+ <literal>inverse="true"</literal>. Pour ces
associations, les mises � jour sont g�r�es
+ au niveau de l'association "plusieurs-vers-un" et les
consid�rations de performance de
+ mise � jour des collections ne s'appliquent tout simplement pas dans
ces cas l�.
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-collections-mostefficentinverse">
+ <title>Les Bags et les lists sont les plus efficaces pour les
collections inverse</title>
+
+ <para>
+ Avant que vous n'oubliez les bags pour toujours, il y a un cas pr�cis
o� les bags
+ (et les lists) sont bien plus performants que les sets. Pour une collection
marqu�e
+ comme <literal>inverse="true"</literal> (le choix le plus
courant pour un relation
+ un vers plusieurs bidirectionnelle), nous pouvons ajouter des �l�ments � un bag
+ ou une list sans avoir besoin de l'initialiser (fetch) les �l�ments du sac!
+ Ceci parce que <literal>Collection.add()</literal> ou
<literal>Collection.addAll()</literal>
+ doit toujours retourner vrai pour un bag ou une
<literal>List</literal>
+ (contrairement au <literal>Set</literal>).
+ Cela peut rendre le code suivant beaucoup plus rapide.
+ </para>
+
+ <programlisting><![CDATA[Parent p = (Parent) sess.load(Parent.class,
id);
+ Child c = new Child();
+ c.setParent(p);
+ p.getChildren().add(c); //pas besoin de charger la collection !
+ sess.flush();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="performance-collections-oneshotdelete">
+ <title>Suppression en un coup</title>
+
+ <para>
+ Parfois, effacer les �l�ments d'une collection un par un peut �tre
extr�mement inefficace.
+ Hibernate n'est pas totalement stupide, il sait qu'il ne faut pas le
faire dans le cas d'une
+ collection compl�tement vid�e (lorsque vous appellez
<literal>list.clear()</literal>, par exemple).
+ Dans ce cas, Hibernate fera un simple <literal>DELETE</literal> et le
travail est fait !
+ </para>
+
+ <para>
+ Supposons que nous ajoutions un �l�ment dans une collection de taille
vingt et que nous
+ enlevions ensuite deux �l�ments. Hibernate effectuera un
<literal>INSERT</literal> puis
+ deux <literal>DELETE</literal> (� moins que la collection ne soit un
bag). Ce qui est
+ souhaitable.
+ </para>
+
+ <para>
+ Cependant, supposons que nous enlevions dix huit �l�ments, laissant ainsi
deux �l�ments, puis
+ que nous ajoutions trois nouveaux �l�ments. Il y a deux moyens de proc�der.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>effacer dix huit enregistrements un � un puis en ins�rer
trois</para>
+ </listitem>
+ <listitem>
+ <para>effacer la totalit� de la collection (en un
<literal>DELETE</literal> SQL) puis ins�rer
+ les cinq �l�ments restant un � un</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate n'est pas assez intelligent pour savoir que, dans ce cas,
la seconde m�thode est plus
+ rapide (Il plut�t heureux qu'Hibernate ne soit pas trop intelligent ; un tel
comportement
+ pourrait rendre l'utilisation de triggers de bases de donn�es plut�t
al�atoire, etc...).
+ </para>
+
+ <para>
+ Heureusement, vous pouvez forcer ce comportement lorsque vous le
souhaitez, en liberant
+ (c'est-�-dire en d�r�f�ren�ant) la collection initiale et en retournant une
collection
+ nouvellement instanci�e avec les �l�ments restants. Ceci peut �tre tr�s pratique
et
+ tr�s puissant de temps en temps.
+ </para>
+
+ <para>
+ Bien s�r, la suppression en un coup ne s'applique pas pour les
collections qui sont mapp�es
+ avec <literal>inverse="true"</literal>.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="performance-monitoring" revision="1">
+ <title>Moniteur de performance</title>
+
+ <para>
+ L'optimisation n'est pas d'un grand int�r�t sans le suivi et
l'acc�s aux donn�es de
+ performance. Hibernate fournit toute une panoplie de rapport sur ses op�rations
internes.
+ Les statistiques dans Hibernate sont fournies par
<literal>SessionFactory</literal>.
+ </para>
+
+ <sect2 id="performance-monitoring-sf" revision="2">
+ <title>Suivi d'une SessionFactory</title>
+
+ <para>
+ Vous pouvez acc�der au m�triques d'une
<literal>SessionFactory</literal> de deux
+ mani�res. La premi�re option est d'appeler
<literal>sessionFactory.getStatistics()</literal>
+ et de lire ou d'afficher les <literal>Statistics</literal>
vous m�me.
+ </para>
+
+ <para>
+ Hibernate peut �galement utiliser JMX pour publier les m�triques si vous
activez
+ le MBean <literal>StatisticsService</literal>. Vous pouvez
activer un seul MBean
+ pour toutes vos <literal>SessionFactory</literal> ou un par
factory. Voici un code
+ qui montre un exemple de configuration minimaliste :
+ </para>
+
+ <programlisting><![CDATA[// MBean service registration for a
specific SessionFactory
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "myFinancialApp");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
+server.registerMBean(stats, on); // Register the Mbean on the
server]]></programlisting>
+
+
+<programlisting><![CDATA[// MBean service registration for all
SessionFactory's
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "all");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+server.registerMBean(stats, on); // Register the MBean on the
server]]></programlisting>
+
+ <para>
+ TODO: Cela n'a pas de sens : dans le premier cs on r�cup�re et on
utilise le MBean directement.
+ Dans le second, on doit fournir le nom JNDI sous lequel est retenu la
fabrique de session avant de
+ l'utiliser. Pour cela il faut utiliser
+
<literal>hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")</literal>
+ </para>
+ <para>
+ Vous pouvez (d�s)activer le suivi pour une
<literal>SessionFactory</literal>
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ au moment de la configuration en mettant
<literal>hibernate.generate_statistics</literal> �
<literal>false</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ � chaud avec
<literal>sf.getStatistics().setStatisticsEnabled(true)</literal>
+ ou
<literal>hibernateStatsBean.setStatisticsEnabled(true)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Les statistiques peuvent �tre remises � z�ro de mani�re programmatique �
l'aide de la m�thode
+ <literal>clear()</literal>
+ Un r�sum� peut �tre envoy� � un logger (niveau info) � l'aide de la
m�thode <literal>logSummary()</literal>
+ </para>
+
+ </sect2>
+
+ <sect2 id="performance-monitoring-metrics"
revision="1">
+ <title>M�triques</title>
+
+ <para>
+ Hibernate fournit un certain nombre de m�triques, qui vont des informations
tr�s basiques
+ aux informations tr�s sp�cialis�es qui ne sont appropri�es que dans
certains scenarii.
+ Tous les compteurs accessibles sont d�crits dans l'API de
l'interface
+ <literal>Statistics</literal> dans trois cat�gories :
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Les m�triques relatives � l'usage g�n�ral de la
<literal>Session</literal>
+ comme le nombre de sessions ouvertes, le nombre de connexions JDBC
r�cup�r�es, etc...
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Les m�triques relatives aux entit�s, collections, requ�tes et
caches dans
+ leur ensemble (m�triques globales),
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Les m�triques d�taill�es relatives � une entit�, une collection,
une requ�te
+ ou une r�gion de cache particuli�re.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Par exemple, vous pouvez v�rifier l'acc�s au cache ainsi que le taux
d'�l�ments manquants et
+ de mise � jour des entit�s, collections et requ�tes et le temps moyen que
met une requ�te.
+ Il faut faire attention au fait que le nombre de millisecondes est sujet �
approximation en
+ Java. Hibernate est li� � la pr�cision de la machine virtuelle, sur
certaines plateformes,
+ cela n'offre qu'une pr�cision de l'ordre de 10 secondes.
+ </para>
+
+ <para>
+ Des accesseurs simples sont utilis�s pour acc�der aux m�triques globales
(e.g. celles qui ne
+ sont pas li�es � une entit�, collection ou r�gion de cache particuli�re).
Vous pouvez acc�der
+ aux m�triques d'une entit�, collection, r�gion de cache particuli�re �
l'aide de son nom et � l'aide
+ de sa repr�sentation HQL ou SQL pour une requ�te. R�f�rez vous � la javadoc
des APIS
+ <literal>Statistics</literal>,
<literal>EntityStatistics</literal>,
+ <literal>CollectionStatistics</literal>,
<literal>SecondLevelCacheStatistics</literal>,
+ and <literal>QueryStatistics</literal> pour plus
d'informations. Le code ci-dessous montre
+ un exemple simple :
+ </para>
+
+ <programlisting><![CDATA[Statistics stats =
HibernateUtil.sessionFactory.getStatistics();
+
+double queryCacheHitCount = stats.getQueryCacheHitCount();
+double queryCacheMissCount = stats.getQueryCacheMissCount();
+double queryCacheHitRatio =
+ queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);
+
+log.info("Query Hit ratio:" + queryCacheHitRatio);
+
+EntityStatistics entityStats =
+ stats.getEntityStatistics( Cat.class.getName() );
+long changes =
+ entityStats.getInsertCount()
+ + entityStats.getUpdateCount()
+ + entityStats.getDeleteCount();
+log.info(Cat.class.getName() + " changed " + changes + "times"
);]]></programlisting>
+
+ <para>
+ Pour travailler sur toutes les entit�s, collections, requ�tes et r�gions de
cache, vous pouvez
+ r�cup�rer la liste des noms des entit�s, collections, requ�tes et r�gions
de cache avec les
+ m�thodes : <literal>getQueries()</literal>,
<literal>getEntityNames()</literal>,
+ <literal>getCollectionRoleNames()</literal>, et
+ <literal>getSecondLevelCacheRegionNames()</literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
Copied:
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/persistent_classes.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/persistent_classes.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/persistent_classes.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/persistent_classes.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,536 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<chapter id="persistent-classes" revision="2">
+ <title>Classes persistantes</title>
+
+ <para>
+ Les classes persistantes sont les classes d'une application qui impl�mentent
+ les entit�s d'un probl�me m�tier (ex. Client et Commande dans une
application
+ de commerce �lectronique).
+ Toutes les instances d'une classe persistante ne sont pas forc�ment
+ dans l'�tat persistant - au lieu de cela, une instance peut �tre �ph�m�re
(NdT : transient) ou d�tach�e.
+ </para>
+
+ <para>
+ Hibernate fonctionne de mani�re optimale lorsque ces classes suivent quelques
r�gles
+ simples, aussi connues comme le mod�le de programmation Plain Old Java Object
+ (POJO). Cependant, aucune de ces r�gles ne sont des besoins absolus. En effet,
Hibernate3 suppose tr�s peu de choses � propos
+ de la nature de vos objets persistants. Vous pouvez exprimer un mod�le de domaine
par d'autres moyens : utiliser des arbres
+ d'instances de <literal>Map</literal>, par exemple.
+ </para>
+
+ <sect1 id="persistent-classes-pojo">
+ <title>Un exemple simple de POJO</title>
+
+ <para>
+ Toute bonne application Java n�cessite une classe persistante
+ repr�sentant les f�lins.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+public class Cat {
+ private Long id; // identifier
+
+ private Date birthdate;
+ private Color color;
+ private char sex;
+ private float weight;
+ private int litterId;
+
+ private Cat mother;
+ private Set kittens = new HashSet();
+
+ private void setId(Long id) {
+ this.id=id;
+ }
+ public Long getId() {
+ return id;
+ }
+
+ void setBirthdate(Date date) {
+ birthdate = date;
+ }
+ public Date getBirthdate() {
+ return birthdate;
+ }
+
+ void setWeight(float weight) {
+ this.weight = weight;
+ }
+ public float getWeight() {
+ return weight;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+ void setColor(Color color) {
+ this.color = color;
+ }
+
+ void setSex(char sex) {
+ this.sex=sex;
+ }
+ public char getSex() {
+ return sex;
+ }
+
+ void setLitterId(int id) {
+ this.litterId = id;
+ }
+ public int getLitterId() {
+ return litterId;
+ }
+
+ void setMother(Cat mother) {
+ this.mother = mother;
+ }
+ public Cat getMother() {
+ return mother;
+ }
+ void setKittens(Set kittens) {
+ this.kittens = kittens;
+ }
+ public Set getKittens() {
+ return kittens;
+ }
+
+ // addKitten not needed by Hibernate
+ public void addKitten(Cat kitten) {
+ kitten.setMother(this);
+ kitten.setLitterId( kittens.size() );
+ kittens.add(kitten);
+ }
+}]]></programlisting>
+
+ <para>
+ Il y a quatre r�gles � suivre ici :
+ </para>
+
+
+ <sect2 id="persistent-classes-pojo-constructor"
revision="1">
+ <title>Impl�menter un constructeur sans argument</title>
+
+ <para>
+ <literal>Cat</literal> a un constructeur sans argument.
Toutes les classes persistantes doivent avoir un
+ constructeur par d�faut (lequel peut ne pas �tre public) pour
qu'Hibernate puissent les instancier en utilisant
+ <literal>Constructor.newInstance()</literal>. Nous
recommandons fortement d'avoir un constructeur par d�faut avec
+ au moins une visibilit� <emphasis>paquet</emphasis> pour la
g�n�ration du proxy � l'ex�cution dans Hibernate.
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-identifier"
revision="2">
+ <title>Fournir une propri�t� d'indentifiant
(optionnel)</title>
+
+ <para>
+ <literal>Cat</literal> poss�de une propri�t� appel�e
<literal>id</literal>.
+ Cette propri�t� mappe la valeur de la colonne de cl� primaire de la
table
+ d'une base de donn�es.La propri�t� aurait pu s'appeler
compl�tement autrement,
+ et son type aurait pu �tre n'importe quel type primitif,
n'importe quel "encapsuleur"
+ de type primitif, <literal>java.lang.String</literal> ou
<literal>java.util.Date</literal>.
+ (Si votre base de donn�es h�rit�e poss�de des cl�s composites, elles
peuvent �tre mapp�es
+ en utilisant une classe d�finie par l'utilisateur et poss�dant les
propri�t�s associ�es aux
+ types de la cl� composite - voir la section concernant les identifiants
composites plus tard).
+ </para>
+
+ <para>
+ La propri�t� d'identifiant est strictement optionnelle. Vous pouver
l'oublier et laisser Hibernate
+ s'occuper des identifiants de l'objet en interne. Toutefois, nous
ne le recommandons pas.
+ </para>
+
+ <para>
+ En fait, quelques fonctionnalit�s ne sont disponibles que pour les
classes
+ d�clarant un identifiant de propri�t� :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Les r�attachements transitifs pour les objets d�tach�s (mise �
jour en cascade ou fusion en cascade) -
+ voir <xref linkend="objectstate-transitive"/>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>Session.merge()</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Nous recommandons que vous d�clariez les propri�t�s d'identifiant de
mani�re
+ uniforme. Nous recommandons �galement que vous utilisiez un type
nullable
+ (ie. non primitif).
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-final">
+ <title>Favoriser les classes non finales (optionnel)</title>
+ <para>
+ Une fonctionnalit� clef d'Hibernate, les
<emphasis>proxies</emphasis>, n�cessitent
+ que la classe persistente soit non finale ou qu'elle soit
l'impl�mentation d'une
+ interface qui d�clare toutes les m�thodes publiques.
+ </para>
+ <para>
+ Vous pouvez persister, gr�ce � Hibernate, les classes
<literal>final</literal>
+ qui n'impl�mentent pas d'interface, mais vous ne pourrez pas
utiliser les proxies pour les chargements d'associations paresseuses
+ - ce qui limitera vos possibilit�s d'ajustement des performances.
+ </para>
+ <para>
+ Vous devriez aussi �viter de d�clarer des m�thodes <literal>public
final</literal> sur des classes
+ non-finales. Si vous voulez utiliser une classe avec une m�thode
<literal>public final</literal>, vous devez
+ explicitement d�sactiver les proxies en param�trant
+ <literal>lazy="false"</literal>.
+ </para>
+ </sect2>
+
+ <sect2 id="persistent-classes-pojo-accessors"
revision="2">
+ <title>D�clarer les accesseurs et mutateurs des attributs persistants
(optionnel)</title>
+
+ <para>
+ <literal>Cat</literal> d�clare des mutateurs pour toutes ses
champs persistants. Beaucoup d'autres
+ solutions de mapping Objet/relationnel persistent directement les
variables d'instance. Nous pensons
+ qu'il est bien mieux de fournir une indirection entre le sch�ma
relationnel et les structures de donn�es internes de la classe.
+ Par d�faut, Hibernate persiste les propri�t�s suivant le style JavaBean,
et reconna�t les noms de m�thodes de la forme <literal>
+ getFoo</literal>, <literal>isFoo</literal> et
+ <literal>setFoo</literal>. Nous pouvons changer pour un acc�s
direct aux champs pour des propri�t�s particuli�res, si besoin est.
+ </para>
+
+ <para>
+ Les propri�t�s <emphasis>n'ont pas</emphasis> � �tre
d�clar�es publiques -
+ Hibernate peut persister une propri�t� avec un paire de getter/setter de
+ visibilit� par d�fault, <literal>protected</literal> ou
<literal>
+ private</literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-inheritance">
+ <title>Impl�menter l'h�ritage</title>
+
+ <para>
+ Une sous-classe doit �galement suivre la premi�re et la seconde r�gle.
+ Elle h�rite sa propri�t� d'identifiant de
<literal>Cat</literal>.
+ </para>
+
+ <programlisting><![CDATA[package eg;
+
+public class DomesticCat extends Cat {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+ protected void setName(String name) {
+ this.name=name;
+ }
+}]]></programlisting>
+ </sect1>
+
+ <sect1 id="persistent-classes-equalshashcode"
revision="1">
+ <title>Impl�menter <literal>equals()</literal> et
<literal>hashCode()</literal></title>
+
+ <para>
+ Vous devez surcharger les m�thodes <literal>equals()</literal>
et
+ <literal>hashCode()</literal> si vous
+ </para>
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ avez l'intention de mettre des instances de classes persistantes
dans un <literal>Set</literal>
+ (la mani�re recommand�e pour repr�senter des associations
pluri-valu�es)
+ <emphasis>et</emphasis>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ avez l'intention d'utiliser le r�attachement d'instances
d�tach�es
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Hibernate garantit l'�quivalence de l'identit� persistante (ligne de
base de donn�es) et l'identit� Java seulement
+ � l'int�rieur de la port�e d'une session particuli�re. Donc d�s que
nous m�langeons des instances venant de diff�rentes
+ sessions, nous devons impl�menter <literal>equals()</literal> et
+ <literal>hashCode()</literal> si nous souhaitons avoir une
s�mantique correcte pour les <literal>Set</literal>s.
+ </para>
+
+ <para>
+ La mani�re la plus �vidente est d'impl�menter
<literal>equals()</literal>/<literal>hashCode()</literal>
+ en comparant la valeur de l'identifiant des deux objets. Si cette valeur
est identique, les deux
+ doivent repr�senter la m�me ligne de base de donn�es, ils sont donc �gaux (si
les deux sont
+ ajout�s � un <literal>Set</literal>, nous n'aurons qu'un
seul �l�ment dans le
+ <literal>Set</literal>). Malheureusement, nous ne pouvons pas
utiliser cette approche avec
+ des identifiants g�n�r�s ! Hibernate n'assignera de
+ valeur d'identifiant qu'aux objets qui sont persistants, une instance
nouvellement cr��e n'aura
+ donc pas de valeur d'identifiant ! De plus, si une instance est non
sauvegard�e et actuellement dans un <literal>Set</literal>,
+ le sauvegarder assignera une valeur d'identifiant � l'objet. Si
<literal>equals()</literal> et <literal>hashCode()</literal>
+ sont bas�es sur la valeur de l'identifiant, le code de hachage devrait
changer, rompant le contrat du <literal>Set</literal>.
+ Regardez sur le site web d'Hibernate pour une discussion compl�te de ce
probl�me.
+ Notez que ceci n'est pas un probl�me d'Hibernate, mais la s�mantique
normale de Java pour l'identit� d'un objet et l'�galit�.
+ </para>
+
+ <para>
+ Nous recommandons donc d'impl�menter
+ <literal>equals()</literal> et
<literal>hashCode()</literal> en utilisant <emphasis>
+ l'�galit� par cl� m�tier</emphasis>.L'�galit� par cl� m�tier
signifie que la m�thode <literal>equals()</literal>
+ compare uniquement les propri�t�s qui forment une cl� m�tier, une cl� qui
+ identifierait notre instance dans le monde r�el (une cl� candidate
+ <emphasis>naturelle</emphasis>) :
+ </para>
+
+ <programlisting><![CDATA[public class Cat {
+
+ ...
+ public boolean equals(Object other) {
+ if (this == other) return true;
+ if ( !(other instanceof Cat) ) return false;
+
+ final Cat cat = (Cat) other;
+
+ if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
+ if ( !cat.getMother().equals( getMother() ) ) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = getMother().hashCode();
+ result = 29 * result + getLitterId();
+ return result;
+ }
+
+}]]></programlisting>
+
+ <para>
+ Notez qu'une clef m�tier ne doit pas �tre solide comme une clef primaire
de base de donn�es
+ (voir <xref linkend="transactions-basics-identity"/>). Les
propri�t�s
+ immuables ou uniques sont g�n�ralement de bonnes candidates pour une clef
m�tier.
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-dynamicmodels">
+ <title>Mod�les dynamiques</title>
+
+ <para>
+ <emphasis>Notez que la fonctionnalit�s suivantes sont actuellement
consid�r�es
+ comme exp�rimentales et peuvent changer dans un futur
proche.</emphasis>
+ </para>
+
+ <para>
+ Les entit�s persistantes ne doivent pas n�cessairement �tre repr�sent�es
comme
+ des classes POJO ou des objets JavaBean � l'ex�cution. Hibernate supporte
aussi les
+ mod�les dynamiques (en utilisant des <literal>Map</literal>s de
<literal>Map</literal>s
+ � l'ex�cution) et la repr�sentation des entit�s comme des arbres DOM4J.
Avec cette
+ approche, vous n'�crivez pas de classes persistantes, seulement des
fichiers de mapping.
+ </para>
+
+ <para>
+ Par d�faut, Hibernate fonctionne en mode POJO normal. Vous pouvez param�trer
+ un mode de repr�sentation d'entit� par d�faut pour une
<literal>SessionFactory</literal>
+ particuli�re en utilisant l'option de configuration
<literal>default_entity_mode</literal>
+ (voir <xref linkend="configuration-optional-properties"/>).
+ </para>
+
+ <para>
+ Les exemples suivants d�montrent la repr�sentation utilisant des
<literal>Map</literal>s.
+ D'abord, dans le fichier de mapping, un
<literal>entity-name</literal> doit �tre d�clar�
+ au lieu (ou en plus) d'un nom de classe :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class entity-name="Customer">
+
+ <id name="id"
+ type="long"
+ column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <property name="name"
+ column="NAME"
+ type="string"/>
+
+ <property name="address"
+ column="ADDRESS"
+ type="string"/>
+
+ <many-to-one name="organization"
+ column="ORGANIZATION_ID"
+ class="Organization"/>
+
+ <bag name="orders"
+ inverse="true"
+ lazy="false"
+ cascade="all">
+ <key column="CUSTOMER_ID"/>
+ <one-to-many class="Order"/>
+ </bag>
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Notez que m�me si des associations sont d�clar�es en utilisant des noms de
classe cible,
+ le type de cible d'une association peut aussi �tre une entit� dynamique
au lieu d'un POJO.
+ </para>
+
+ <para>
+ Apr�s avoir configur� le mode d'entit� par d�faut �
<literal>dynamic-map</literal>
+ pour la <literal>SessionFactory</literal>, nous pouvons lors de
l'ex�cution fonctionner
+ avec des <literal>Map</literal>s de
<literal>Map</literal>s :
+ </para>
+
+ <programlisting><![CDATA[Session s = openSession();
+Transaction tx = s.beginTransaction();
+Session s = openSession();
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+
+// Create an organization
+Map foobar = new HashMap();
+foobar.put("name", "Foobar Inc.");
+
+// Link both
+david.put("organization", foobar);
+
+// Save both
+s.save("Customer", david);
+s.save("Organization", foobar);
+
+tx.commit();
+s.close();]]></programlisting>
+
+ <para>
+ Les avantages d'un mapping dynamique sont un gain de temps pour le
prototypage
+ sans la n�cessit� d'impl�menter les classes d'entit�. Pourtant, vous
perdez la
+ v�rification du typage au moment de la compilation et aurez plus
d'exceptions �
+ g�rer lors de l'ex�cution. Gr�ce au mapping d'Hibernate, le sch�ma de
la base de
+ donn�es peut facilement �tre normalis� et solidifi�, permettant de rajouter
une
+ impl�mentation propre du mod�le de domaine plus tard.
+ </para>
+
+ <para>
+ Les modes de repr�sentation d'une entit� peut aussi �tre configur� par
<literal>Session</literal> :
+ </para>
+
+ <programlisting><![CDATA[Session dynamicSession =
pojoSession.getSession(EntityMode.MAP);
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+dynamicSession.save("Customer", david);
+...
+dynamicSession.flush();
+dynamicSession.close()
+...
+// Continue on pojoSession
+]]></programlisting>
+
+
+ <para>
+ Veuillez noter que l'appel � <literal>getSession()</literal>
en utilisant un
+ <literal>EntityMode</literal> se fait sur l'API
<literal>Session</literal>, pas
+ <literal>SessionFactory</literal>. De cette mani�re, la nouvelle
<literal>Session</literal>
+ partage les connexions JDBC, transactions et autres informations de contexte
sous-jacentes.
+ Cela signifie que vous n'avez pas � appeler
<literal>flush()</literal> et <literal>close()</literal>
+ sur la <literal>Session</literal> secondaire, et laissez aussi la
gestion de la transaction
+ et de la connexion � l'unit� de travail primaire.
+ </para>
+
+ <para>
+ Plus d'informations � propos de la repr�sentation XML peuvent �tre
trouv�es dans
+ <xref linkend="xml"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="persistent-classes-tuplizers" revision="0">
+ <title>Tuplizers</title>
+
+ <para>
+ <literal>org.hibernate.tuple.Tuplizer</literal>, et ses
sous-interfaces, sont responsables
+ de la gestion d'une repr�sentation particuli�re d'un morceau de
donn�es, en fonction du
+ <literal>org.hibernate.EntityMode</literal> de r�pr�sentation. Si
un morceau donn� de donn�es
+ est pens� comme une structure de donn�es, alors un tuplizer est la chose qui
sait comment
+ cr�er une telle structure de donn�es, comment extraire des valeurs et
injecter des valeurs dans
+ une telle structure de donn�es. Par exemple, pour le mode d'entit� POJO,
le tuplizer correspondant
+ sait comment cr�er le POJO � travers son constructeur et comment acc�der aux
propri�t�s du POJO
+ utilisant les accesseurs de la propri�t� d�finie. Il y a deux types de
Tuplizers haut niveau,
+ repr�sent� par les interfaces
<literal>org.hibernate.tuple.EntityTuplizer</literal> et
+ <literal>org.hibernate.tuple.ComponentTuplizer</literal>. Les
<literal>EntityTuplizer</literal>s
+ sont responsables de la gestion des contrats mentionn�s ci-dessus pour les
entit�s, alors que
+ les <literal>ComponentTuplizer</literal>s s'occupent des
composants.
+ </para>
+
+ <para>
+ Les utilisateurs peuvent aussi brancher leurs propres tuplizers. Peut-�tre
vous est-il n�cessaire qu'une
+ impl�mentation de <literal>java.util.Map</literal> autre que
<literal>java.util.HashMap</literal>
+ soit utilis�e dans le mode d'entit� dynamic-map ; ou peut-�tre avez-vous
besoin de d�finir une
+ stat�gie de g�n�ration de proxy diff�rente de celle utilis�e par d�faut. Les
deux devraient �tre
+ effectu�es en d�finissant une impl�mentation de tuplizer utilisateur. Les
d�finitions de tuplizers
+ sont attach�es au mapping de l'entit� ou du composant qu'ils sont
cens�s g�rer. Retour � l'exemple de
+ notre entit� utilisateur :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+ <class entity-name="Customer">
+ <!--
+ Override the dynamic-map entity-mode
+ tuplizer for the customer entity
+ -->
+ <tuplizer entity-mode="dynamic-map"
+ class="CustomMapTuplizerImpl"/>
+
+ <id name="id" type="long" column="ID">
+ <generator class="sequence"/>
+ </id>
+
+ <!-- other properties -->
+ ...
+ </class>
+</hibernate-mapping>
+
+
+public class CustomMapTuplizerImpl
+ extends org.hibernate.tuple.DynamicMapEntityTuplizer {
+ // override the buildInstantiator() method to plug in our custom map...
+ protected final Instantiator buildInstantiator(
+ org.hibernate.mapping.PersistentClass mappingInfo) {
+ return new CustomMapInstantiator( mappingInfo );
+ }
+
+ private static final class CustomMapInstantiator
+ extends org.hibernate.tuple.DynamicMapInstantitor {
+ // override the generateMap() method to return our custom map...
+ protected final Map generateMap() {
+ return new CustomMap();
+ }
+ }
+}]]></programlisting>
+
+
+ </sect1>
+
+ <para>
+ TODO: Document user-extension framework in the property and proxy packages
+ </para>
+
+</chapter>
+
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/preface.xml
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/preface.xml
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/content/preface.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,112 @@
+<?xml version='1.0'?>
+
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<preface id="preface">
+ <title>Préface</title>
+
+ <para>
+ Travailler dans les deux univers que sont l'orienté objet et la base de
données
+ relationnelle peut être lourd et consommateur en temps dans le monde de
+ l'entreprise d'aujourd'hui. Hibernate est un outil de mapping
objet/relationnel
+ pour le monde Java. Le terme mapping objet/relationnel (ORM) décrit la technique
+ consistant à faire le lien entre la représentation objet des données
+ et sa représentation relationnelle basée sur un schéma SQL.
+ </para>
+
+ <para>
+ Non seulement, Hibernate s'occupe du transfert des classes Java dans les
tables
+ de la base de données (et des types de données Java dans les types de données
SQL),
+ mais il permet de requêter les données et propose des moyens de les récupérer.
+ Il peut donc réduire de manière significative le temps de développement qui
+ aurait été autrement perdu dans une manipulation manuelle des données via SQL
+ et JDBC.
+ </para>
+
+ <para>
+ Le but d'Hibernate est de libérer le développeur de 95 pourcent des tâches
de
+ programmation liées à la persistance des données communes. Hibernate n'est
+ probablement pas la meilleure solution pour les applications centrées sur les
+ données qui n'utilisent que les procédures stockées pour implémenter la
logique
+ métier dans la base de données, il est le plus utile dans les modèles métier
orientés
+ objets dont la logique métier est implémentée dans la couche Java dite
intermédiaire.
+ Cependant, Hibernate vous aidera à supprimer ou à encapsuler le code SQL
+ spécifique à votre base de données et vous aidera sur la tâche commune
qu'est
+ la transformation des données d'une représentation tabulaire à une
+ représentation sous forme de graphe d'objets.
+ </para>
+
+ <para>
+ Si vous êtes nouveau dans Hibernate et le mapping Objet/Relationnel voire même en
Java,
+ suivez ces quelques étapes :
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ Lisez <xref linkend="tutorial"/> pour un didacticiel plus
long avec plus d'instructions étape par étape.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Lisez <xref linkend="architecture"/> pour comprendre les
environnements dans lesquels
+ Hibernate peut être utilisé.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Regardez le répertoire <literal>eg</literal> de la
distribution Hibernate, il contient
+ une application simple et autonome. Copiez votre pilote JDBC dans le
répertoire
+ <literal>lib/</literal> et éditez
<literal>src/hibernate.properties</literal>, en
+ positionnant correctement les valeurs pour votre base de données. A
partir d'une
+ invite de commande dans le répertoire de la distribution, tapez
<literal>ant eg</literal>
+ (cela utilise Ant), ou sous Windows tapez <literal>build
eg</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Faîtes de cette documentation de référence votre principale source
d'information.
+ Pensez à lire <emphasis>Java Persistence with
Hibernate</emphasis>
+ (
http://www.manning.com/bauer2) si vous avez besoin de plus d'aide
avec le design
+ d'applications ou si vous préférez un tutoriel pas à pas. Visitez
aussi
+
http://caveatemptor.hibernate.org et téléchargez l'application
exemple
+ pour Java Persistence with Hibernate.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Les questions les plus fréquemment posées (FAQs) trouvent leur réponse
sur le
+ site web Hibernate.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Des démos, exemples et tutoriaux de tierces personnes sont référencés
sur
+ le site web Hibernate.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ La zone communautaire (Community Area) du site web Hibernate est une
+ bonne source d'information sur les design patterns et sur
différentes
+ solutions d'intégration d'Hibernate (Tomcat, JBoss, Spring
Framework, Struts,
+ EJB, etc).
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ Si vous avez des questions, utilisez le forum utilisateurs du site web
Hibernate.
+ Nous utilisons également l'outil de gestion des incidents JIRA pour tout ce
qui
+ est rapports de bogue et demandes d'évolution. Si vous êtes intéressé par
le
+ développement d'Hibernate, joignez-vous à la liste de diffusion de
développement.
+ </para>
+
+ <para>
+ Le développement commercial, le support de production et les formations à
Hibernate
+ sont proposés par JBoss Inc (voir
http://www.hibernate.org/SupportTraining/).
Hibernate
+ est un projet Open Source professionnel et un composant critique de la suite de
produits
+ JBoss Enterprise Middleware System (JEMS).
+ </para>
+
+ </preface>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_criteria.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/query_criteria.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_criteria.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_criteria.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,443 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="querycriteria">
+ <title>Requ�tes par crit�res</title>
+
+ <para>
+ Hibernate offre une API d'interrogation par crit�res intuitive et
extensible.
+ </para>
+
+ <sect1 id="querycriteria-creating">
+ <title>Cr�er une instance de
<literal>Criteria</literal></title>
+
+ <para>
+ L'interface <literal>net.sf.hibernate.Criteria</literal>
repr�sente une requ�te sur une
+ classe persistente donn�e. La <literal>Session</literal> fournit
les instances de
+ <literal>Criteria</literal>.
+ </para>
+
+ <programlisting><![CDATA[Criteria crit =
sess.createCriteria(Cat.class);
+crit.setMaxResults(50);
+List cats = crit.list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-narrowing">
+ <title>Restriction du r�sultat</title>
+
+ <para>
+ Un criterion (crit�re de recherche) est une instance de l'interface
+ <literal>org.hibernate.criterion.Criterion</literal>. La classe
+ <literal>org.hibernate.criterion.Restrictions</literal> d�finit
+ des m�thodes pour obtenir des types de
<literal>Criterion</literal>
+ pr�-d�finis.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.between("weight", minWeight, maxWeight) )
+ .list();]]></programlisting>
+
+ <para>
+ Les restrictions peuvent �tre goup�es de mani�re logique.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .add( Restrictions.or(
+ Restrictions.eq( "age", new Integer(0) ),
+ Restrictions.isNull("age")
+ ) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.in( "name", new String[] { "Fritz",
"Izi", "Pk" } ) )
+ .add( Restrictions.disjunction()
+ .add( Restrictions.isNull("age") )
+ .add( Restrictions.eq("age", new Integer(0) ) )
+ .add( Restrictions.eq("age", new Integer(1) ) )
+ .add( Restrictions.eq("age", new Integer(2) ) )
+ ) )
+ .list();]]></programlisting>
+
+ <para>
+ Il y a plusieurs types de criterion pr�-d�finis (sous classes de
<literal>Restriction</literal>),
+ mais l'une d'entre elle particuli�rement utile vous permet de
sp�cifier directement
+ du SQL.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.sql("lower({alias}.name) like lower(?)",
"Fritz%", Hibernate.STRING) )
+ .list();]]></programlisting>
+
+ <para>
+ La zone <literal>{alias}</literal> sera remplac�e par l'alias
de colonne de l'entit�
+ que l'on souhaite int�rroger.
+ </para>
+
+ <para>
+ Une autre approche pour obtenir un criterion est de le r�cup�rer d'une
instance de <literal>Property</literal>.
+ Vous pouvez cr�er une <literal>Property</literal> en appelant
<literal>Property.forName()</literal>.
+ </para>
+
+ <programlisting><![CDATA[
+Property age = Property.forName("age");
+List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.disjunction()
+ .add( age.isNull() )
+ .add( age.eq( new Integer(0) ) )
+ .add( age.eq( new Integer(1) ) )
+ .add( age.eq( new Integer(2) ) )
+ ) )
+ .add( Property.forName("name").in( new String[] { "Fritz",
"Izi", "Pk" } ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-ordering">
+ <title>Trier les r�sultats</title>
+
+ <para>
+ Vous pouvez trier les r�sultats en utilisant
<literal>org.hibernate.criterion.Order</literal>.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%")
+ .addOrder( Order.asc("name") )
+ .addOrder( Order.desc("age") )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Property.forName("name").like("F%") )
+ .addOrder( Property.forName("name").asc() )
+ .addOrder( Property.forName("age").desc() )
+ .setMaxResults(50)
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-associations" revision="2">
+ <title>Associations</title>
+
+ <para>
+ Vous pouvez facilement sp�cifier des contraintes sur des entit�s li�es,
+ par des associations en utilisant
<literal>createCriteria()</literal>.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "F%")
+ .createCriteria("kittens")
+ .add( Restrictions.like("name", "F%")
+ .list();]]></programlisting>
+
+ <para>
+ Notez que la seconde <literal>createCriteria()</literal> retourne
une nouvelle
+ instance de <literal>Criteria</literal>, qui se rapporte aux
�l�ments de la
+ collection <literal>kittens</literal>.
+ </para>
+
+ <para>
+ La forme alternative suivante est utile dans certains cas.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createAlias("kittens", "kt")
+ .createAlias("mate", "mt")
+ .add( Restrictions.eqProperty("kt.name", "mt.name") )
+ .list();]]></programlisting>
+
+ <para>
+ (<literal>createAlias()</literal> ne cr�e pas de nouvelle
instance de
+ <literal>Criteria</literal>.)
+ </para>
+
+ <para>
+ Notez que les collections kittens contenues dans les instances de
<literal>Cat</literal>
+ retourn�es par les deux pr�c�dentes requ�tes ne sont
<emphasis>pas</emphasis> pr�-filtr�es
+ par les crit�res ! Si vous souhaitez r�cup�rer uniquement les kittens qui
correspondent � la
+ criteria, vous devez utiliser
<literal>ResultTransformer</literal>.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .createCriteria("kittens", "kt")
+ .add( Restrictions.eq("name", "F%") )
+ .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
+ .list();
+Iterator iter = cats.iterator();
+while ( iter.hasNext() ) {
+ Map map = (Map) iter.next();
+ Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
+ Cat kitten = (Cat) map.get("kt");
+}]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-dynamicfetching" revision="1">
+ <title>Peuplement d'associations de mani�re dynamique</title>
+
+ <para>
+ Vous pouvez sp�ficier au moment de l'ex�cution le peuplement d'une
association en utilisant
+ <literal>setFetchMode()</literal> (c'est-�-dire le chargement
de celle-ci).
+ Cela permet de surcharger les valeurs
+ "lazy" et "outer-join" du mapping.
+ </para>
+
+ <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+ .add( Restrictions.like("name", "Fritz%") )
+ .setFetchMode("mate", FetchMode.EAGER)
+ .setFetchMode("kittens", FetchMode.EAGER)
+ .list();]]></programlisting>
+
+ <para>
+ Cette requ�te recherchera <literal>mate</literal> et
<literal>kittens</literal>
+ via les jointures externes. Voir <xref
linkend="performance-fetching"/> pour plus d'informations.
+ </para>
+
+ </sect1>
+
+ <sect1 id="querycriteria-examples">
+ <title>Requ�tes par l'exemple</title>
+
+ <para>
+ La classe <literal>org.hibernate.criterion.Example</literal> vous
permet de
+ construire un crit�re suivant une instance d'objet donn�e.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = new Cat();
+cat.setSex('F');
+cat.setColor(Color.BLACK);
+List results = session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .list();]]></programlisting>
+
+ <para>
+ Les propri�t�s de type version, identifiant et association sont ignor�es.
+ Par d�faut, les valeurs null sont exclues.
+ </para>
+
+ <para>
+ Vous pouvez ajuster la strat�gie d'utilisation de valeurs de
+ l'<literal>Exemple</literal>.
+ </para>
+
+ <programlisting><![CDATA[Example example = Example.create(cat)
+ .excludeZeroes() //exclude zero valued properties
+ .excludeProperty("color") //exclude the property named "color"
+ .ignoreCase() //perform case insensitive string comparisons
+ .enableLike(); //use like for string comparisons
+List results = session.createCriteria(Cat.class)
+ .add(example)
+ .list();]]></programlisting>
+
+ <para>
+ Vous pouvez utiliser les "exemples" pour des crit�res sur les
objets associ�s.
+ </para>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Cat.class)
+ .add( Example.create(cat) )
+ .createCriteria("mate")
+ .add( Example.create( cat.getMate() ) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-projection">
+ <title>Projections, agr�gation et regroupement</title>
+ <para>
+ La classe <literal>org.hibernate.criterion.Projections</literal>
est une
+ fabrique d'instances de <literal>Projection</literal>. Nous
appliquons une
+ projection sur une requ�te en appelant
<literal>setProjection()</literal>.
+ </para>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Cat.class)
+ .setProjection( Projections.rowCount() )
+ .add( Restrictions.eq("color", Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount() )
+ .add( Projections.avg("weight") )
+ .add( Projections.max("weight") )
+ .add( Projections.groupProperty("color") )
+ )
+ .list();]]></programlisting>
+
+ <para>
+ Il n'y a pas besoin de "group by" explicite dans une requ�te
par crit�re.
+ Certains types de projection sont d�finis pour �tre des
<emphasis>projections
+ de regroupement</emphasis>, lesquels apparaissent aussi dans la clause
+ <literal>group by</literal> SQL.
+ </para>
+
+ <para>
+ Un alias peut optionnellement �tre assign� � une projection, ainsi la valeur
+ projet�e peut �tre r�f�renc�e dans des restrictions ou des tris. Voici deux
fa�ons
+ diff�rentes de faire �a :
+ </para>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Cat.class)
+ .setProjection( Projections.alias( Projections.groupProperty("color"),
"colr" ) )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Cat.class)
+ .setProjection( Projections.groupProperty("color").as("colr") )
+ .addOrder( Order.asc("colr") )
+ .list();]]></programlisting>
+
+ <para>
+ Les m�thodes <literal>alias()</literal> et
<literal>as()</literal> enveloppe simplement
+ une instance de projection dans une autre instance (alias�e) de
<literal>Projection</literal>.
+ Comme un raccourci, vous pouvez assignez un alias lorsque vous ajoutez la
projection � la
+ liste de projections :
+ </para>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount(), "catCountByColor" )
+ .add( Projections.avg("weight"), "avgWeight" )
+ .add( Projections.max("weight"), "maxWeight" )
+ .add( Projections.groupProperty("color"), "color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Domestic.class, "cat")
+ .createAlias("kittens", "kit")
+ .setProjection( Projections.projectionList()
+ .add( Projections.property("cat.name"), "catName" )
+ .add( Projections.property("kit.name"), "kitName" )
+ )
+ .addOrder( Order.asc("catName") )
+ .addOrder( Order.asc("kitName") )
+ .list();]]></programlisting>
+
+ <para>
+ Vous pouvez aussi utiliser <literal>Property.forName()</literal>
pour formuler des projections :
+ </para>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Cat.class)
+ .setProjection( Property.forName("name") )
+ .add( Property.forName("color").eq(Color.BLACK) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[List results =
session.createCriteria(Cat.class)
+ .setProjection( Projections.projectionList()
+ .add( Projections.rowCount().as("catCountByColor") )
+ .add( Property.forName("weight").avg().as("avgWeight") )
+ .add( Property.forName("weight").max().as("maxWeight") )
+ .add( Property.forName("color").group().as("color" )
+ )
+ .addOrder( Order.desc("catCountByColor") )
+ .addOrder( Order.desc("avgWeight") )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="querycriteria-detachedqueries">
+ <title>Requ�tes et sous-requ�tes d�tach�es</title>
+ <para>
+ La classe <literal>DetachedCriteria</literal> vous laisse cr�er
une requ�te en dehors de la
+ port�e de la session, et puis l'ex�cuter plus tard en utilisant
n'importe quelle <literal>Session</literal>
+ arbitraire.
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria query =
DetachedCriteria.forClass(Cat.class)
+ .add( Property.forName("sex").eq('F') );
+
+Session session = ....;
+Transaction txn = session.beginTransaction();
+List results = query.getExecutableCriteria(session).setMaxResults(100).list();
+txn.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Une <literal>DetachedCriteria</literal> peut aussi �tre utilis�e
pour exprimer une
+ sous-requ�te. Des instances de criterion impliquant des sous-requ�tes peuvent
�tre
+ obtenues via <literal>Subqueries</literal> ou
<literal>Property</literal>.
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeight =
DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight").avg() );
+session.createCriteria(Cat.class)
+ .add( Property.forName("weight").gt(avgWeight) )
+ .list();]]></programlisting>
+
+ <programlisting><![CDATA[DetachedCriteria weights =
DetachedCriteria.forClass(Cat.class)
+ .setProjection( Property.forName("weight") );
+session.createCriteria(Cat.class)
+ .add( Subqueries.geAll("weight", weights) )
+ .list();]]></programlisting>
+
+ <para>
+ M�me des requ�tes corr�l�es sont possibles :
+ </para>
+
+ <programlisting><![CDATA[DetachedCriteria avgWeightForSex =
DetachedCriteria.forClass(Cat.class, "cat2")
+ .setProjection( Property.forName("weight").avg() )
+ .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
+session.createCriteria(Cat.class, "cat")
+ .add( Property.forName("weight").gt(avgWeightForSex) )
+ .list();]]></programlisting>
+
+ </sect1>
+
+ <!--TODO: ResultSetTransformer + aliasing. AliasToBeanTransformer allow
returning arbitrary
+ user objects - similar to setResultClass in JDO2. General use of
ResultTransformer
+ could also be explained. -->
+
+ <sect1 id="query-criteria-naturalid">
+ <title>Requ�tes par identifiant naturel</title>
+
+ <para>
+ Pour la plupart des requ�tes, incluant les requ�tes par crit�re, le cache de
requ�tes
+ n'est pas tr�s efficace, parce que l'invalidation du cache de
requ�tes arrive trop
+ souvent. Cependant, il y a une sorte sp�ciale de requ�te o� nous pouvons
optimiser
+ l'algorithme d'invalidation du cache : les recherches sur une clef
naturelle constante.
+ Dans certaines applications, cette sorte de requ�te se produit fr�quemment.
L'API de
+ crit�re fournit une provision sp�ciale pour ce cas d'utilisation.
+ </para>
+
+ <para>
+ D'abord vous devriez mapper la clef naturelle de votre entit� en
utilisant
+ <literal><natural-id></literal>, et activer
l'utilisation du cache de second niveau.
+ </para>
+
+ <programlisting><![CDATA[<class name="User">
+ <cache usage="read-write"/>
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <natural-id>
+ <property name="name"/>
+ <property name="org"/>
+ </natural-id>
+ <property name="password"/>
+</class>]]></programlisting>
+
+ <para>
+ Notez que cette fonctionnalit� n'est pas pr�vue pour l'utilisation
avec des
+ entit�s avec des clefs naturelles <emphasis>mutables</emphasis>.
+ </para>
+
+ <para>
+ Ensuite, activez le cache de requ�te d'Hibernate.
+ </para>
+
+ <para>
+ Maintenant <literal>Restrictions.naturalId()</literal> nous
permet de rendre
+ l'utilisation de l'algorithme de cache plus efficace.
+ </para>
+
+ <programlisting><![CDATA[session.createCriteria(User.class)
+ .add( Restrictions.naturalId()
+ .set("name", "gavin")
+ .set("org", "hb")
+ ).setCacheable(true)
+ .uniqueResult();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_hql.xml (from
rev 14070, core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/query_hql.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_hql.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_hql.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,1149 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="queryhql">
+ <title>HQL: Langage de requ�tage d'Hibernate</title>
+
+ <para>
+ Hibernate fourni un langage d'interrogation extr�mement puissant qui
+ ressemble (et c'est voulu) au SQL. Mais ne soyez pas distraits par la syntaxe
;
+ HQL est totalement orient� objet, comprenant des notions d'h�ritage, de
+ polymorphisme et d'association.
+ </para>
+
+ <sect1 id="queryhql-casesensitivity">
+ <title>Sensibilit� � la casse</title>
+
+ <para>
+ Les requ�tes sont insensibles � la casse, � l'exception des noms des
classes Java
+ et des propri�t�s.
+ Ainsi, <literal>SeLeCT</literal> est identique �
+ <literal>sELEct</literal> et �
+ <literal>SELECT</literal> mais
+ <literal>net.sf.hibernate.eg.FOO</literal> n'est pas
identique
+ <literal>net.sf.hibernate.eg.Foo</literal> et
+ <literal>foo.barSet</literal> n'est pas identique �
+ <literal>foo.BARSET</literal>.
+ </para>
+
+ <para>
+ Ce guide utilise les mots cl�s HQL en minuscule. Certains utilisateurs
trouvent les
+ requ�tes �crites avec les mots cl�s en majuscule plus lisibles, mais nous
trouvons
+ cette convention p�nible lorsqu'elle est lue dans du code Java.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-from">
+ <title>La clause from</title>
+
+ <para>
+ La requ�te Hibernate la plus simple est de la forme :
+ </para>
+
+ <programlisting><![CDATA[from eg.Cat]]></programlisting>
+
+ <para>
+ qui retourne simplement toutes les instances de la classe
<literal>eg.Cat</literal>.
+ Nous n'avons pas besoin d'habitude de qualifier le nom de la classe,
+ puisque <literal>auto-import</literal> est la valeur par d�faut.
Donc nous �crivons presque toujours :
+ </para>
+
+ <programlisting><![CDATA[from Cat]]></programlisting>
+
+ <para>
+ La plupart du temps, vous devrez assigner un
<emphasis>alias</emphasis> puisque vous
+ voudrez faire r�f�rence � <literal>Cat</literal> dans
d'autres parties de la requ�te.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ Cette requ�te assigne l'alias <literal>cat</literal> �
l'instance <literal>Cat</literal>,
+ nous pouvons donc utiliser cet alias ailleurs dans la requ�te. Le mot cl�
<literal>as</literal>
+ est optionnel ; nous aurions pu �crire :
+ </para>
+
+ <programlisting><![CDATA[from Cat cat]]></programlisting>
+
+ <para>
+ Plusieurs classes peuvent appara�tre, ce qui conduira � un produit
+ cart�sien (encore appel� jointures crois�es).
+ </para>
+
+ <programlisting><![CDATA[from Formula,
Parameter]]></programlisting>
+ <programlisting><![CDATA[from Formula as form, Parameter as
param]]></programlisting>
+
+ <para>
+ C'est une bonne pratique que de nommer les alias dans les requ�tes en
utilisant l'initiale
+ en miniscule, ce qui a le m�rite d'�tre en phase avec les standards de
+ nommage Java pour les variables locales
(<literal>domesticCat</literal>).
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins" revision="1">
+ <title>Associations et jointures</title>
+
+ <para>
+ On peut aussi assigner des alias � des entit�s associ�es, ou m�me aux
�l�ments d'une collection
+ de valeurs, en utilisant un <literal>join</literal> (jointure).
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join cat.mate as mate
+ left outer join cat.kittens as kitten]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat left join cat.mate.kittens as
kittens]]></programlisting>
+
+ <programlisting><![CDATA[from Formula form full join form.parameter
param]]></programlisting>
+
+ <para>
+ Les types de jointures support�es sont celles de ANSI SQL
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>inner join</literal> (jointure ferm�e)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>left outer join</literal> (jointure ouverte par
la gauche)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>right outer join</literal> (jointure ouverte par
la droite)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>full join</literal> (jointure ouverte totalement
- g�n�ralement inutile)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Les constructions des jointures <literal>inner join</literal>,
<literal>left outer join</literal>
+ et <literal>right outer join</literal> peuvent �tre abbr�g�es.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ join cat.mate as mate
+ left join cat.kittens as kitten]]></programlisting>
+
+ <para>
+ Nous pouvons soumettre des conditions de jointure suppl�mentaires en
utilisant le mot-clef HQL <literal>with</literal>.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ left join cat.kittens as kitten
+ with kitten.bodyWeight > 10.0]]></programlisting>
+
+ <para>
+ Par ailleurs, une jointure "fetch�e" (rapport�e) permet
d'initialiser
+ les associations ou collections de valeurs en m�me temps que leur objet
parent,
+ le tout n'utilisant qu'un seul Select.
+ Ceci est particuli�rement utile dans le cas des collections. Ce syst�me
permet de surcharger
+ les d�clarations "lazy" et "outer-join" des fichiers de
mapping pour les associations et
+ collections. Voir
+ <xref linkend="performance-fetching"/> pour plus
d'informations.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join fetch cat.mate
+ left join fetch cat.kittens]]></programlisting>
+
+ <para>
+ Une jointure "fetch�e" (rapport�e) n'a g�n�ralement pas besoin
de se voir assigner
+ un alias puisque les objets associ�s n'ont pas � �tre utilis�s dans les
autres clauses.
+ Notez aussi que les objets associ�s ne sont pas retourn�s directement dans le
r�sultat de
+ la requ�te mais l'on peut y acc�der via l'objet parent. La seule
raison pour laquelle nous
+ pourrions avoir besoin d'un alias est si nous r�cup�rions r�cursivement
une collection suppl�mentaire :
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+ inner join fetch cat.mate
+ left join fetch cat.kittens child
+ left join fetch child.kittens]]></programlisting>
+
+ <para>
+ Notez que la construction de <literal>fetch</literal> ne peut pas
�tre utilis�e dans les requ�tes appel�es par
+ <literal>scroll()</literal> ou
<literal>iterate()</literal>.
+ <literal>fetch</literal> ne devrait pas non plus �tre utilis�
avec <literal>setMaxResults()</literal> ou
+ <literal>setFirstResult()</literal>.
<literal>fetch</literal> ne peut pas non plus �tre utilis� avec une
+ condition <literal>with</literal> ad hoc. Il est
+ possible de cr�er un produit cart�sien par jointure en r�cup�rant plus
d'une collection dans une requ�te,
+ donc faites attention dans ce cas. R�cup�rer par jointure de multiples
collections donne aussi parfois
+ des r�sultats inattendus pour des mappings de bag, donc soyez prudent lorsque
vous formulez vos requ�tes dans de tels cas.
+ Finalement, notez que <literal>full join fetch</literal> et
<literal>right join fetch</literal> ne sont pas utiles en g�n�ral.
+ </para>
+
+ <para>
+ Si vous utilisez un chargement retard� pour les propri�t�s (avec une
instrumentation par bytecode), il est possible
+ de forcer Hibernate � r�cup�rer les propri�t�s non encore charg�es
imm�diatement (dans la premi�re requ�te)
+ en utilisant <literal>fetch all properties</literal>.
+ </para>
+
+ <programlisting><![CDATA[from Document fetch all properties order by
name]]></programlisting>
+ <programlisting><![CDATA[from Document doc fetch all properties where
lower(doc.name) like '%cats%']]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-joins-forms">
+ <title>Formes de syntaxes pour les jointures</title>
+
+ <para>
+ HQL supporte deux formes pour joindre les associations:
<literal>implicite</literal> et <literal>explicite</literal>.
+ </para>
+
+ <para>
+ Les requ�tes pr�sentes dans la section pr�c�dente utilisent la forme
<literal>explicite</literal>
+ o� le mode cl� join est explicitement utilis� dans la clause from. C'est
la forme recommand�e.
+ </para>
+
+ <para>
+ La forme <literal>implicite</literal> n'utilise pas le mot
cl� join.
+ A la place, les associations sont "d�r�f�renc�es" en utilisant le
notation '.'. Ces
+ jointures peuvent apparaitre dans toutes les clauses. Les jointures
<literal>implicites</literal>
+ r�sultent en des inner join dans le SQL g�n�r�.
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.mate.name like
'%s%']]></programlisting>
+ </sect1>
+
+ <sect1 id="queryhql-select">
+ <title>La clause select</title>
+
+ <para>
+ La clause <literal>select</literal> s�lectionne les objets et
propri�t�s
+ qui doivent �tre retourn�s dans le r�sultat de la requ�te.
+ Soit :
+ </para>
+
+ <programlisting><![CDATA[select mate
+from Cat as cat
+ inner join cat.mate as mate]]></programlisting>
+
+ <para>
+ La requ�te recherchera les <literal>mate</literal>s li�s aux
<literal>Cat</literal>s.
+ Vous pouvez explimer la requ�te d'une mani�re plus compacte :
+ </para>
+
+ <programlisting><![CDATA[select cat.mate from Cat
cat]]></programlisting>
+
+ <para>
+ Les requ�tes peuvent retourner des propri�t�s de n'importe quel type,
m�me celles de type
+ composant (component) :
+ </para>
+
+ <programlisting><![CDATA[select cat.name from DomesticCat cat
+where cat.name like 'fri%']]></programlisting>
+
+ <programlisting><![CDATA[select cust.name.firstName from Customer as
cust]]></programlisting>
+
+ <para>
+ Les requ�tes peuvent retourner plusieurs objets et/ou propri�t�s sous la
forme
+ d'un tableau du type <literal>Object[]</literal>,
+ </para>
+
+ <programlisting><![CDATA[select mother, offspr, mate.name
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ ou sous la forme d'une <literal>List</literal>,
+ </para>
+
+ <programlisting><![CDATA[select new list(mother, offspr, mate.name)
+from DomesticCat as mother
+ inner join mother.mate as mate
+ left outer join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ ou sous la forme d'un objet Java typ�,
+ </para>
+
+ <programlisting><![CDATA[select new Family(mother, mate, offspr)
+from DomesticCat as mother
+ join mother.mate as mate
+ left join mother.kittens as offspr]]></programlisting>
+
+ <para>
+ � condition que la classe <literal>Family</literal> poss�de le
constructeur appropri�.
+ </para>
+
+ <para>
+ Vous pouvez assigner des alias aux expressions s�lectionn�es en utilisant
<literal>as</literal> :
+ </para>
+
+ <programlisting><![CDATA[select max(bodyWeight) as max, min(bodyWeight)
as min, count(*) as n
+from Cat cat]]></programlisting>
+
+ <para>
+ C'est surtout utile lorsque c'est utilis� avec
+ <literal>select new map</literal> :
+ </para>
+
+ <programlisting><![CDATA[select new map( max(bodyWeight) as max,
min(bodyWeight) as min, count(*) as n )
+from Cat cat]]></programlisting>
+
+ <para>
+ Cette requ�te retourne une <literal>Map</literal> � partir des
alias vers les valeurs s�lectionn�es.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-aggregation">
+ <title>Fonctions d'aggr�gation</title>
+
+ <para>
+ Les requ�tes HQL peuvent aussi retourner le r�sultat de fonctions
d'aggr�gation
+ sur les propri�t�s :
+ </para>
+
+ <programlisting><![CDATA[select avg(cat.weight), sum(cat.weight),
max(cat.weight), count(cat)
+from Cat cat]]></programlisting>
+
+<!-- NO LONGER SUPPORTED
+ <para>
+ Collections may also appear inside aggregate functions in the
<literal>select</literal>
+ clause.
+ </para>
+
+ <programlisting><![CDATA[select cat, count( elements(cat.kittens) )
+from Cat cat group by cat]]></programlisting>
+-->
+
+ <para>
+ Les fonctions support�es sont
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>avg(...), sum(...), min(...),
max(...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(*)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>count(...), count(distinct ...),
count(all...)</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Vous pouvez utiliser des op�rateurs arithm�tiques, la concat�nation, et des
fonctions SQL reconnues dans la clause select :
+ </para>
+
+ <programlisting><![CDATA[select cat.weight + sum(kitten.weight)
+from Cat cat
+ join cat.kittens kitten
+group by cat.id, cat.weight]]></programlisting>
+
+ <programlisting><![CDATA[select firstName||' '||initial||'
'||upper(lastName) from Person]]></programlisting>
+
+ <para>
+ Les mots cl� <literal>distinct</literal> et
<literal>all</literal> peuvent �tre utilis�s et ont
+ la m�me signification qu'en SQL.
+ </para>
+
+ <programlisting><![CDATA[select distinct cat.name from Cat cat
+
+select count(distinct cat.name), count(cat) from Cat cat]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-polymorphism">
+ <title>Requ�tes polymorphiques</title>
+
+ <para>
+ Une requ�te comme:
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+ <para>
+ retourne non seuleument les instances de <literal>Cat</literal>,
mais aussi celles des
+ sous classes comme <literal>DomesticCat</literal>. Les requ�tes
Hibernate peuvent nommer n'importe
+ quelle classe ou interface Java dans la clause
<literal>from</literal>. La requ�te retournera les
+ instances de toutes les classes persistantes qui �tendent cette classe ou
impl�mente cette interface.
+ La requ�te suivante retournera tous les objets persistants :
+ </para>
+
+ <programlisting><![CDATA[from java.lang.Object
o]]></programlisting>
+
+ <para>
+ L'interface <literal>Named</literal> peut �tre impl�ment�e
par plusieurs classes persistantes :
+ </para>
+
+ <programlisting><![CDATA[from Named n, Named m where n.name =
m.name]]></programlisting>
+
+ <para>
+ Notez que ces deux derni�res requ�tes n�cessitent plus d'un
<literal>SELECT</literal> SQL.
+ Ce qui signifie que la clause <literal>order by</literal> ne trie
pas correctement la totalit�
+ des r�sultats (cela signifie aussi que vous ne pouvez ex�cuter ces requ�tes
en appelant
+ <literal>Query.scroll()</literal>).
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-where">
+ <title>La clause where</title>
+
+ <para>
+ La clause <literal>where</literal> vous permet de r�duire la
liste des instances retourn�es.
+ Si aucun alias n'existe, vous pouvez vous r�f�rer aux propri�t�s par leur
nom :
+ </para>
+
+ <programlisting><![CDATA[from Cat where
name='Fritz']]></programlisting>
+
+ <para>
+ S'il y a un alias, utilisez un nom de propri�t� qualifi� :
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where
cat.name='Fritz']]></programlisting>
+
+ <para>
+ retourne les instances de <literal>Cat</literal> dont name est
�gale � 'Fritz'.
+ </para>
+
+ <programlisting><![CDATA[select foo
+from Foo foo, Bar bar
+where foo.startDate = bar.date]]></programlisting>
+
+ <para>
+ retournera les instances de <literal>Foo</literal> pour
lesquelles
+ il existe une instance de <literal>bar</literal> avec la
+ propri�t� <literal>date</literal> est �gale � la
+ propri�t� <literal>startDate</literal> de
<literal>Foo</literal>.
+ Les expressions utilisant la navigation rendent la clause
<literal>where</literal>
+ extr�mement puissante. Soit :
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.mate.name is not
null]]></programlisting>
+
+ <para>
+ Cette requ�te se traduit en SQL par une jointure interne � une table.
+ Si vous souhaitez �crire quelque chose comme :
+ </para>
+
+ <programlisting><![CDATA[from Foo foo
+where foo.bar.baz.customer.address.city is not null]]></programlisting>
+
+ <para>
+ vous finiriez avec une requ�te qui n�cessiterait quatre jointures en SQL.
+ </para>
+
+ <para>
+ L'op�rateur <literal>=</literal> peut �tre utilis� pour
comparer aussi bien des propri�t�s que des instances :
+ </para>
+
+ <programlisting><![CDATA[from Cat cat, Cat rival where cat.mate =
rival.mate]]></programlisting>
+
+ <programlisting><![CDATA[select cat, mate
+from Cat cat, Cat mate
+where cat.mate = mate]]></programlisting>
+
+ <para>
+ La propri�t� sp�ciale (en minuscule) <literal>id</literal> peut
�tre utilis�e
+ pour faire r�f�rence � l'identifiant d'un objet (vous pouvez aussi
utiliser
+ le nom de cette propri�t�).
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat where cat.id = 123
+
+from Cat as cat where cat.mate.id = 69]]></programlisting>
+
+ <para>
+ La seconde requ�te est particuli�rement efficace. Aucune jointure n'est
n�cessaire !
+ </para>
+
+ <para>
+ Les propri�t�s d'un identifiant compos� peuvent aussi �tre utilis�es.
Supposez que
+ <literal>Person</literal> ait un identifiant compos� de
<literal>country</literal> et
+ <literal>medicareNumber</literal>.
+ </para>
+
+ <programlisting><![CDATA[from bank.Person person
+where person.id.country = 'AU'
+ and person.id.medicareNumber = 123456]]></programlisting>
+
+ <programlisting><![CDATA[from bank.Account account
+where account.owner.id.country = 'AU'
+ and account.owner.id.medicareNumber = 123456]]></programlisting>
+
+ <para>
+ Une fois de plus, la seconde requ�te ne n�cessite pas de jointure.
+ </para>
+
+ <para>
+ De m�me, la propri�t� sp�ciale <literal>class</literal> interroge
la valeur discriminante
+ d'une instance dans le cas d'une persistance polymorphique. Le nom
d'une classe Java incorpor�e
+ dans la clause where sera traduite par sa valeur discriminante.
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.class =
DomesticCat]]></programlisting>
+
+ <para>
+ Vous pouvez aussi sp�cifier les propri�t�s des composants ou types
utilisateurs compos�s
+ (components, composite user types etc). N'essayez jamais d'utiliser
un expression de navigation
+ qui se terminerait par une propri�t� de type composant (qui est diff�rent
d'une propri�t� d'un
+ composant). Par exemple, si <literal>store.owner</literal> est
une entit� avec un composant
+ <literal>address</literal>
+ </para>
+
+ <programlisting><![CDATA[store.owner.address.city // okay
+store.owner.address // error!]]></programlisting>
+
+ <para>
+ Un type "any" poss�de les propri�t�s sp�ciales
<literal>id</literal> et <literal>class</literal>,
+ qui nous permettent d'exprimer une jointure de la mani�re suivante (o�
<literal>AuditLog.item</literal>
+ est une propri�t� mapp�e avec
<literal><any></literal>).
+ </para>
+
+ <programlisting><![CDATA[from AuditLog log, Payment payment
+where log.item.class = 'Payment' and log.item.id =
payment.id]]></programlisting>
+
+ <para>
+ Dans la requ�te pr�c�dente, notez que
<literal>log.item.class</literal> et
<literal>payment.class</literal>
+ feraient r�f�rence � des valeurs de colonnes de la base de donn�es
compl�tement diff�rentes.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-expressions">
+ <title>Expressions</title>
+
+ <para>
+ Les expressions permises dans la clause <literal>where</literal>
incluent
+ la plupart des choses que vous pouvez utiliser en SQL :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ op�rateurs math�matiques <literal>+, -, *, /</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ op�rateur de comparaison binaire <literal>=, >=,
<=, <>, !=, like</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ op�rateurs logiques <literal>and, or, not</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Parenth�ses <literal>( )</literal>, indiquant un
regroupement
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>in</literal>,
+ <literal>not in</literal>,
+ <literal>between</literal>,
+ <literal>is null</literal>,
+ <literal>is not null</literal>,
+ <literal>is empty</literal>,
+ <literal>is not empty</literal>,
+ <literal>member of</literal> and
+ <literal>not member of</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ "Simple" case, <literal>case ... when ... then ...
else ... end</literal>, and
+ "searched" case, <literal>case when ... then ... else
... end</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ concatenation de cha�ne de caract�res
<literal>...||...</literal> ou <literal>concat(...,...)</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>current_date()</literal>,
<literal>current_time()</literal>,
+ <literal>current_timestamp()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>second(...)</literal>,
<literal>minute(...)</literal>,
+ <literal>hour(...)</literal>,
<literal>day(...)</literal>,
+ <literal>month(...)</literal>,
<literal>year(...)</literal>,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ N'importe quel fonction ou op�rateur d�fini par EJB-QL 3.0 :
<literal>substring(), trim(),
+ lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(),
mod()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>coalesce()</literal> et
<literal>nullif()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>str()</literal> pour convertir des valeurs
num�riques ou temporelles vers une cha�ne de caract�res lisible
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>cast(... as ...)</literal>, o� le second
argument est le nom d'un type Hibernate, et <literal>extract(... from
...)</literal> si le
+ <literal>cast()</literal> ANSI et
<literal>extract()</literal> sont support�s par la base de donn�es
sous-jacente
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ La fonction HQL <literal>index()</literal>, qui
s'applique aux alias d'une collection index�e jointe
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Les fonctions HQL qui s'appliquent expressions repr�sentant des
collections : <literal>size(),
+ minelement(), maxelement(), minindex(), maxindex()</literal>,
ainsi que les fonctions sp�ciales <literal>elements()</literal>
+ et <literal>indices</literal> qui peuvent �tre
quantifi�es en utilisant <literal>some, all, exists, any, in</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ N'importe quelle fonction scalaire support�e par la base de
donn�es comme
+ <literal>sign()</literal>,
+ <literal>trunc()</literal>,
<literal>rtrim()</literal>, <literal>sin()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Les param�tres positionnels de JDBC
+ <literal>?</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ param�tres nomm�s <literal>:name</literal>,
<literal>:start_date</literal>, <literal>:x1</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ litt�ral SQL <literal>'foo'</literal>,
<literal>69</literal>, <literal>'1970-01-01
10:00:01.0'</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Constantes Java <literal>public static final</literal>
<literal>eg.Color.TABBY</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>in</literal> et <literal>between</literal>
peuvent �tre utilis�s comme suit :
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name between
'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name in (
'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ et la forme n�gative peut �tre �crite
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not between
'A' and 'B']]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat cat where cat.name not in (
'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+ <para>
+ De m�me, <literal>is null</literal> et <literal>is not
null</literal> peuvent �tre utilis�s pour tester
+ les valeurs nulle.
+ </para>
+
+ <para>
+ Les bool�ens peuvent �tre facilement utilis�s en d�clarant les substitutions
de requ�tes dans la
+ configuration Hibernate :
+ </para>
+
+ <programlisting><![CDATA[<property
name="hibernate.query.substitutions">true 1, false
0</property>]]></programlisting>
+
+ <para>
+ Ce qui remplacera les mots cl�s <literal>true</literal> et
<literal>false</literal> par
+ <literal>1</literal> et <literal>0</literal> dans la
traduction SQL du HQL suivant :
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.alive =
true]]></programlisting>
+
+ <para>
+ Vous pouvez tester la taille d'une collection par la propri�t� sp�ciale
<literal>size</literal>, ou
+ la fonction sp�ciale <literal>size()</literal>.
+ </para>
+
+ <programlisting><![CDATA[from Cat cat where cat.kittens.size >
0]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where size(cat.kittens) >
0]]></programlisting>
+
+ <para>
+ Pour les collections index�es, vous pouvez faire r�f�rence aux indices
minimum et maximum en
+ utilisant les fonctions <literal>minindex</literal> and
<literal>maxindex</literal>. De mani�re similaire,
+ vous pouvez faire r�f�rence aux �l�ments minimum et maximum d'une
collection de type basiques
+ en utilisant les fonctions <literal>minelement</literal> et
<literal>maxelement</literal>.
+ </para>
+
+ <programlisting><![CDATA[from Calendar cal where
maxelement(cal.holidays) > current date]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where maxindex(order.items)
> 100]]></programlisting>
+
+ <programlisting><![CDATA[from Order order where minelement(order.items)
> 10000]]></programlisting>
+
+ <para>
+ Les fonctions SQL <literal>any, some, all, exists, in</literal>
supportent que leur soient pass�es
+ l'�l�ment, l'index d'une collection (fonctions
<literal>elements</literal> et <literal>indices</literal>)
+ ou le r�sultat d'une sous requ�te (voir ci dessous).
+ </para>
+
+ <programlisting><![CDATA[select mother from Cat as mother, Cat as kit
+where kit in elements(foo.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[select p from NameList list, Person p
+where p.name = some elements(list.names)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat cat where exists
elements(cat.kittens)]]></programlisting>
+
+ <programlisting><![CDATA[from Player p where 3 > all
elements(p.scores)]]></programlisting>
+
+ <programlisting><![CDATA[from Show show where 'fizard' in
indices(show.acts)]]></programlisting>
+
+ <para>
+ Notez que l'�criture de - <literal>size</literal>,
<literal>elements</literal>,
+ <literal>indices</literal>,
<literal>minindex</literal>, <literal>maxindex</literal>,
+ <literal>minelement</literal>,
<literal>maxelement</literal> - peuvent seulement �tre utilis�e dans la clause
where dans Hibernate3.
+ </para>
+
+ <para>
+ Les �l�ments de collections index�es (arrays, lists, maps) peuvent �tre
r�f�renc�s via index
+ (dans une clause where seulement) :
+ </para>
+
+ <programlisting><![CDATA[from Order order where order.items[0].id =
1234]]></programlisting>
+
+ <programlisting><![CDATA[select person from Person person, Calendar
calendar
+where calendar.holidays['national day'] = person.birthDay
+ and person.nationality.calendar = calendar]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ order.deliveredItemIndices[0] ] = item and order.id =
11]]></programlisting>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ maxindex(order.items) ] = item and order.id =
11]]></programlisting>
+
+ <para>
+ L'expression entre <literal>[]</literal> peut m�me �tre une
expression arithm�tique.
+ </para>
+
+ <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ size(order.items) - 1 ] = item]]></programlisting>
+
+ <para>
+ HQL propose aussi une fonction <literal>index()</literal>
interne, pour les �l�ments
+ d'une association one-to-many ou d'une collections de valeurs.
+ </para>
+
+ <programlisting><![CDATA[select item, index(item) from Order order
+ join order.items item
+where index(item) < 5]]></programlisting>
+
+ <para>
+ Les fonctions SQL scalaires support�es par la base de donn�es utilis�e
peuvent �tre utilis�es
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat where upper(cat.name) like
'FRI%']]></programlisting>
+
+ <para>
+ Si vous n'�tes pas encore convaincu par tout cela, imaginez la taille et
l'illisibilit� qui caract�riseraient
+ la transformation SQL de la requ�te HQL suivante :
+ </para>
+
+ <programlisting><![CDATA[select cust
+from Product prod,
+ Store store
+ inner join store.customers cust
+where prod.name = 'widget'
+ and store.location.name in ( 'Melbourne', 'Sydney' )
+ and prod = all elements(cust.currentOrder.lineItems)]]></programlisting>
+
+ <para>
+ <emphasis>Un indice :</emphasis> cela donnerait quelque chose
comme
+ </para>
+
+ <programlisting><![CDATA[SELECT cust.name, cust.address, cust.phone,
cust.id, cust.current_order
+FROM customers cust,
+ stores store,
+ locations loc,
+ store_customers sc,
+ product prod
+WHERE prod.name = 'widget'
+ AND store.loc_id = loc.id
+ AND loc.name IN ( 'Melbourne', 'Sydney' )
+ AND sc.store_id = store.id
+ AND sc.cust_id = cust.id
+ AND prod.id = ALL(
+ SELECT item.prod_id
+ FROM line_items item, orders o
+ WHERE item.order_id = o.id
+ AND cust.current_order = o.id
+ )]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-ordering">
+ <title>La clause order by</title>
+
+ <para>
+ La liste retoun�e par la requ�te peut �tre tri�e par n'importe quelle
propri�t� de la classe ou
+ du composant retourn� :
+ </para>
+
+ <programlisting><![CDATA[from DomesticCat cat
+order by cat.name asc, cat.weight desc, cat.birthdate]]></programlisting>
+
+ <para>
+ Le mot optionnel <literal>asc</literal> ou
<literal>desc</literal> indique respectivement si le tri
+ doit �tre croissant ou d�croissant.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-grouping">
+ <title>La clause group by</title>
+
+ <para>
+ Si la requ�te retourne des valeurs aggr�g�es, celles ci peuvent �tre group�es
par propri�t� ou composant :
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color]]></programlisting>
+
+ <programlisting><![CDATA[select foo.id, avg(name), max(name)
+from Foo foo join foo.names name
+group by foo.id]]></programlisting>
+
+ <para>
+ Une clause <literal>having</literal> est aussi permise.
+ </para>
+
+ <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
+from Cat cat
+group by cat.color
+having cat.color in (eg.Color.TABBY, eg.Color.BLACK)]]></programlisting>
+
+ <para>
+ Les fonctions SQL et les fonctions d'aggr�gations sont permises dans les
clauses <literal>having</literal>
+ et <literal>order by</literal>, si elles sont support�es par la
base de donn�es (ce que ne fait pas MySQL par exemple).
+ </para>
+
+ <programlisting><![CDATA[select cat
+from Cat cat
+ join cat.kittens kitten
+group by cat
+having avg(kitten.weight) > 100
+order by count(kitten) asc, sum(kitten.weight) desc]]></programlisting>
+
+ <para>
+ Notez que ni la clause <literal>group by</literal> ni la clause
+ <literal>order by</literal> ne peuvent contenir d'expressions
arithm�tiques.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-subqueries" revision="2">
+ <title>Sous-requ�tes</title>
+
+ <para>
+ Pour les bases de donn�es le supportant, Hibernate supporte les sous requ�tes
dans les requ�tes.
+ Une sous requ�te doit �tre entre parenth�ses (souvent pour un appel � une
fonction d'agr�gation SQL)
+ M�me les sous requ�tes corr�l�es (celles qui font r�f�rence � un alias de la
requ�te principale) sont
+ support�es.
+ </para>
+
+ <programlisting><![CDATA[from Cat as fatcat
+where fatcat.weight > (
+ select avg(cat.weight) from DomesticCat cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name = some (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[from Cat as cat
+where not exists (
+ from Cat as mate where mate.mate = cat
+)]]></programlisting>
+
+ <programlisting><![CDATA[from DomesticCat as cat
+where cat.name not in (
+ select name.nickName from Name as name
+)]]></programlisting>
+
+ <programlisting><![CDATA[select cat.id, (select max(kit.weight) from
cat.kitten kit)
+from Cat as cat]]></programlisting>
+
+ <para>
+ Notez que les sous-requ�tes HQL peuvent arriver seulememnt dans les clauses
select ou where.
+ </para>
+
+ <para>
+ Pour des sous-requ�tes avec plus d'une expression dans le select, vous
pouvez utiliser un constructeur de tuples :
+ </para>
+
+ <programlisting><![CDATA[from Cat as cat
+where not ( cat.name, cat.color ) in (
+ select cat.name, cat.color from DomesticCat cat
+)]]></programlisting>
+
+ <para>
+ Notez que sur certaines bases de donn�es (mais par Oracle ou HSQL), vous
pouvez utiliser des constructeurs de tuples
+ dans d'autres contextes, par exemple lors du requ�tage de composants ou
de types utilisateur composites :
+ </para>
+
+ <programlisting><![CDATA[from Person where name = ('Gavin',
'A', 'King')]]></programlisting>
+
+ <para>
+ Ce qui est �quivalent � la forme plus verbeuse suivante :
+ </para>
+
+ <programlisting><![CDATA[from Person where name.first = 'Gavin'
and name.initial = 'A' and name.last =
'King')]]></programlisting>
+
+ <para>
+ Il y a deux bonnes raisons que vous ne puissiez ne pas vouloir faire cette
sorte de choses : d'abord, ce n'est
+ pas compl�tement portable entre les plateformes de base de donn�es ;
deuxi�mement, la requ�te est maintenant
+ d�pendante de l'ordre des propri�t�s dans le document de mapping.
+ </para>
+
+ </sect1>
+
+ <sect1 id="queryhql-examples">
+ <title>Exemples HQL</title>
+
+ <para>
+ Les requ�tes Hibernate peuvent �tre relativement puissantes et complexes. En
fait, la puissance
+ du langage de requ�tage est l'un des avantages principaux
d'Hibernate. Voici quelques exemples
+ tr�s similaires aux requ�tes que nous avons utilis�es lors d'un r�cent
projet. Notez que la plupart
+ des requ�tes que vous �crirez seront plus simples que les exemples suivantes !
+ </para>
+
+ <para>
+ La requ�te suivante retourne l'id de commande (order), le nombre
d'articles (items) et la valeur
+ totale de la commande (order) pour toutes les commandes non pay�es d'un
client (customer) particulier
+ pour un total minimum donn�, le tout tri� par la valeur totale. La requ�te
SQL g�n�r�e sur les tables
+ <literal>ORDER</literal>,
<literal>ORDER_LINE</literal>, <literal>PRODUCT</literal>,
+ <literal>CATALOG</literal> et
<literal>PRICE</literal> est compos�e de quatre jointures interne ainsi que
+ d'une sous-requ�te (non corr�l�e).
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount),
count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog.effectiveDate < sysdate
+ and catalog.effectiveDate >= all (
+ select cat.effectiveDate
+ from Catalog as cat
+ where cat.effectiveDate < sysdate
+ )
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ Quel monstre !
+ En principe, nous ne sommes pas tr�s fan des sous-requ�tes, la requ�te
ressemblait donc plut�t
+ � cela :
+ </para>
+
+ <programlisting><![CDATA[select order.id, sum(price.amount),
count(item)
+from Order as order
+ join order.lineItems as item
+ join item.product as product,
+ Catalog as catalog
+ join catalog.prices as price
+where order.paid = false
+ and order.customer = :customer
+ and price.product = product
+ and catalog = :currentCatalog
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+
+ <para>
+ La requ�te suivante compte le nombre de paiements (payments) pour chaque
status, en excluant
+ les paiements dans le status <literal>AWAITING_APPROVAL</literal>
o� le changement de status
+ le plus r�cent � �t� fait par l'utilisateur courant. En SQL, cette
requ�te effectue deux
+ jointures internes et des sous requ�tes corr�l�es sur les tables
<literal>PAYMENT</literal>,
+ <literal>PAYMENT_STATUS</literal> et
<literal>PAYMENT_STATUS_CHANGE</literal>.
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+ join payment.statusChanges as statusChange
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or (
+ statusChange.timeStamp = (
+ select max(change.timeStamp)
+ from PaymentStatusChange change
+ where change.payment = payment
+ )
+ and statusChange.user <> :currentUser
+ )
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ Si nous avions mapp� la collection
<literal>statusChanges</literal> comme une liste, au lieu d'un ensemble,
+ la requ�te aurait �t� plus facile � �crire.
+ </para>
+
+ <programlisting><![CDATA[select count(payment), status.name
+from Payment as payment
+ join payment.currentStatus as status
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+ or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <>
:currentUser
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+ <para>
+ La requ�te qui suit utilise la fonction de MS SQL
<literal>isNull()</literal> pour retourner
+ tous les comptes (accounts) et paiements (payments) impay�s pour
l'organisation � laquelle
+ l'uilisateur (user) courant appartient. Elle est traduite en SQL par
trois jointures internes,
+ une jointure externe ainsi qu'une sous requ�te sur les tables
<literal>ACCOUNT</literal>, <literal>PAYMENT</literal>,
+ <literal>PAYMENT_STATUS</literal>,
<literal>ACCOUNT_TYPE</literal>, <literal>ORGANIZATION</literal>
et
+ <literal>ORG_USER</literal>.
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ left outer join account.payments as payment
+where :currentUser in elements(account.holder.users)
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber,
payment.dueDate]]></programlisting>
+
+ <para>
+ Pour d'autres base de donn�es, nous aurions d� faire sans la sous-requ�te
(corr�l�e).
+ </para>
+
+ <programlisting><![CDATA[select account, payment
+from Account as account
+ join account.holder.users as user
+ left outer join account.payments as payment
+where :currentUser = user
+ and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber,
payment.dueDate]]></programlisting>
+
+ </sect1>
+
+ <sect1 id="queryhql-bulk" revision="2">
+ <title>Mise � jour et suppression</title>
+
+ <para>
+ HQL supporte maintenant les expressions
<literal>update</literal>, <literal>delete</literal> et
+ <literal>insert ... select ...</literal>.
+ Voir <xref linkend="batch-direct"/> pour les d�tails.
+ </para>
+ </sect1>
+
+ <sect1 id="queryhql-tipstricks">
+ <title>Trucs & Astuces</title>
+
+ <para>
+ Vous pouvez compter le nombre de r�sultats d'une requ�te sans les
retourner :
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select
count(*) from ....").iterate().next() ).intValue()]]></programlisting>
+
+ <para>
+ Pour trier les r�sultats par la taille d'une collection, utilisez la
requ�te suivante :
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+order by count(msg)]]></programlisting>
+
+ <para>
+ Si votre base de donn�es supporte les sous-requ�tes, vous pouvez placer des
+ conditions sur la taille de la s�lection dans la clause where de votre requ�te:
+ </para>
+
+ <programlisting><![CDATA[from User usr where size(usr.messages) >=
1]]></programlisting>
+
+ <para>
+ Si votre base de donn�es ne supporte pas les sous-requ�tes, utilisez la
requ�te suivante :
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User usr.name
+ join usr.messages msg
+group by usr.id, usr.name
+having count(msg) >= 1]]></programlisting>
+
+ <para>
+ Cette solution ne peut pas retourner un <literal>User</literal>
avec z�ro message
+ � cause de la jointure interne, la forme suivante peut donc �tre utile :
+ </para>
+
+ <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+ left join usr.messages as msg
+group by usr.id, usr.name
+having count(msg) = 0]]></programlisting>
+
+ <para>
+ Les propri�t�s d'un JavaBean peuvent �tre inject�es dans les param�tres
nomm�s d'un requ�te :
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createQuery("from foo Foo as
foo where foo.name=:name and foo.size=:size");
+q.setProperties(fooBean); // fooBean has getName() and getSize()
+List foos = q.list();]]></programlisting>
+
+ <para>
+ Les collections sont paginables via l'utilisation de l'interface
<literal>Query</literal> avec un filtre :
+ </para>
+
+ <programlisting><![CDATA[Query q = s.createFilter( collection,
"" ); // the trivial filter
+q.setMaxResults(PAGE_SIZE);
+q.setFirstResult(PAGE_SIZE * pageNumber);
+List page = q.list();]]></programlisting>
+
+ <para>
+ Les �l�ments d'une collection peuvent �tre tri�s ou group�s en utilisant
un filtre de requ�te :
+ </para>
+
+ <programlisting><![CDATA[Collection orderedCollection = s.filter(
collection, "order by this.amount" );
+Collection counts = s.filter( collection, "select this.type, count(this) group by
this.type" );]]></programlisting>
+
+ <para>
+ Vous pouvez r�cup�rer la taille d'une collection sans l'initialiser
:
+ </para>
+
+ <programlisting><![CDATA[( (Integer) session.createQuery("select
count(*) from ....").iterate().next() ).intValue();]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_sql.xml (from
rev 14070, core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/query_sql.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_sql.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/query_sql.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,606 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<chapter id="querysql" revision="2">
+ <title>SQL natif</title>
+
+ <para>
+ Vous pouvez aussi �crire vos requ�tes dans le dialecte SQL natif de votre base de
donn�es.
+ Ceci est utile si vous souhaitez utiliser les fonctionnalit�s sp�cifiques de
votre base de
+ donn�es comme le mot cl� <literal>CONNECT</literal> d'Oracle.
Cette fonctionnalit� offre par ailleurs un moyen
+ de migration plus propre et doux d'une application bas�e sur SQL/JDBC vers
+ une application Hibernate.
+ </para>
+
+ <para>Hibernate3 vous permet de sp�cifier du SQL �crit � la main (incluant les
proc�dures stock�es)
+ pour toutes les op�rations de cr�ation, mise � jour, suppression et
chargement.</para>
+
+ <sect1 id="querysql-creating" revision="3">
+ <title>Utiliser une <literal>SQLQuery</literal></title>
+
+ <para>L'ex�cution des requ�tes en SQL natif est contr�l�e par
l'interface <literal>SQLQuery</literal>,
+ laquelle est obtenue en appelant
<literal>Session.createSQLQuery()</literal>.
+ Dans des cas extr�mement simples, nous pouvons utiliser la forme suivante :
+ </para>
+
+ <programlisting>List cats = sess.createSQLQuery("select * from
cats")
+ .addEntity(Cat.class)
+ .list();</programlisting>
+
+ <para>Cette requ�te a sp�cifi� :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>la requ�te SQL</para>
+ </listitem>
+
+ <listitem>
+ <para>l'entit� retourn�e par la requ�te</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Ici, les noms de colonne des r�sultats sont suppos�s �tre les m�mes que les noms
de colonne sp�cifi�s dans le
+ document de mapping. Cela peut �tre probl�matique pour des requ�tes SQL qui
joignent de multiple tables, puisque
+ les m�mes noms de colonne peuvent appara�tre dans plus d'une table. La forme
suivante n'est pas vuln�rable � la
+ duplication des noms de colonne :
+ </para>
+
+ <programlisting>List cats = sess.createSQLQuery("select {cat.*} from cats
cat")
+ .addEntity("cat", Cat.class)
+ .list();</programlisting>
+
+ <para>Cette requ�te a sp�cifi� :</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>la requ�te SQL, avec un param�tre fictif pour Hibernate pour injecter
les alias de colonne</para>
+ </listitem>
+
+ <listitem>
+ <para>l'entit� retourn�e par la requ�te, et son alias de table
SQL</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ La m�thode <literal>addEntity()</literal> associe l'alias de la
table SQL
+ avec la classe de l'entit� retourn�e, et d�termine la forme de l'ensemble
des r�sultats de la requ�te.
+ </para>
+
+ <para>
+ La m�thode <literal>addJoin()</literal> peut �tre utilis�e pour
charger des associations vers d'autres
+ entit�s et collections.
+ </para>
+
+ <programlisting>List cats = sess.createSQLQuery(
+ "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother =
cat.id"
+ )
+ .addEntity("cat", Cat.class)
+ .addJoin("kitten", "cat.kittens")
+ .list();</programlisting>
+
+ <para>
+ Une requ�te SQL native pourrait retourner une simple valeur scalaire ou une
combinaison de scalaires et d'entit�s.
+ </para>
+
+ <programlisting>Double max = (Double) sess.createSQLQuery("select
max(cat.weight) as maxWeight from cats cat")
+ .addScalar("maxWeight", Hibernate.DOUBLE);
+ .uniqueResult();</programlisting>
+
+ <para>Vous pouvez alternativement d�crire les informations de mapping des
r�sultats dans vos fichiers hbm
+ et les utiliser pour vos requ�tes.</para>
+
+ <programlisting>List cats = sess.createSQLQuery(
+ "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother =
cat.id"
+ )
+ .setResultSetMapping("catAndKitten")
+ .list();</programlisting>
+ </sect1>
+
+ <sect1 id="querysql-aliasreferences">
+ <title>Alias et r�f�rences de propri�t�</title>
+
+ <para>
+ La notation <literal>{cat.*}</literal> utilis�e au-dessus est un
raccourci pour "toutes les propri�t�s".
+ Alternativement, vous pouvez lister explicitement les colonnes, mais m�me ce cas
que nous laissons � Hibernate
+ injecte des alias de colonne SQL pour chaque propri�t�. Le rempla�ant pour un
alias de colonne
+ est juste le nom de la propri�t� qualifi� par l'alias de la table.
+ Dans l'exemple suivant, nous r�cup�rons des
<literal>Cat</literal>s � partir d'une table diff�rente
+ (<literal>cat_log</literal>) de celle d�clar�e dans les m�ta-donn�es
de mapping.
+ Notez que nous pouvons m�me utiliser les alias de propri�t� dans la clause
"where" si nous le souhaitons.
+ </para>
+
+ <para>
+ La syntaxe <literal>{}</literal> <emphasis>n'est
pas</emphasis> requise pour le requ�tes nomm�es. Voir
+ <xref linkend="querysql-namedqueries" />.
+ </para>
+
+ <programlisting>String sql = "select cat.originalId as {cat.id}, " +
+ "cat.mateid as {cat.mate}, cat.sex as {cat.sex}, " +
+ "cat.weight*10 as {cat.weight}, cat.name as {cat.name} " +
+ "from cat_log cat where {cat.mate} = :catId"
+
+List loggedCats = sess.createSQLQuery(sql)
+ .addEntity("cat", Cat.class)
+ .setLong("catId", catId)
+ .list();</programlisting>
+
+ <para>
+ <emphasis>� noter :</emphasis> si vous listez chaque propri�t�
explicitement, vous devez inclure
+ toutes les propri�t�s de la classe <emphasis>et ses
sous-classes</emphasis> !
+ </para>
+
+ <para>
+ La table suivante montre les diff�rentes possibilit�s d'utilisation de
l'injection d'alias. � noter : les noms
+ des alias dans le r�sultat sont des exemples, chaque alias aura un nom unique et
probablement diff�rent lors de l'utilisation.
+ </para>
+
+ <table frame="topbot" id="aliasinjection-summary">
+ <title>Noms d'injection d'alias</title>
+
+ <tgroup cols="4">
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="1*" />
+
+ <colspec colwidth="2.5*" />
+
+ <thead>
+ <row>
+ <entry>Description</entry>
+
+ <entry>Syntaxe</entry>
+
+ <entry>Exemple</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Une simple propri�t�</entry>
+
+
<entry><literal>{[aliasname].[propertyname]}</literal></entry>
+
+ <entry><literal>A_NAME as
{item.name}</literal></entry>
+ </row>
+
+ <row>
+ <entry>Une propri�t� compos�e</entry>
+
+
<entry><literal>{[aliasname].[componentname].[propertyname]}</literal></entry>
+
+ <entry><literal>CURRENCY as {item.amount.currency}, VALUE as
+ {item.amount.value}</literal></entry>
+ </row>
+
+ <row>
+ <entry>Discriminant d'une entit�</entry>
+
+
<entry><literal>{[aliasname].class}</literal></entry>
+
+ <entry><literal>DISC as
{item.class}</literal></entry>
+ </row>
+
+ <row>
+ <entry>Toutes les propri�t�s d'une entit�</entry>
+
+ <entry><literal>{[aliasname].*}</literal></entry>
+
+ <entry><literal>{item.*}</literal></entry>
+ </row>
+
+ <row>
+ <entry>Une clef de collection</entry>
+
+ <entry><literal>{[aliasname].key}</literal></entry>
+
+ <entry><literal>ORGID as
{coll.key}</literal></entry>
+ </row>
+
+ <row>
+ <entry>L'identifiant d'une collection</entry>
+
+ <entry><literal>{[aliasname].id}</literal></entry>
+
+ <entry><literal>EMPID as {coll.id}</literal></entry>
+ </row>
+
+ <row>
+ <entry>L'�l�ment d'une collection</entry>
+
+
<entry><literal>{[aliasname].element}</literal></entry>
+
+ <entry><literal>XID as
{coll.element}</literal></entry>
+
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>Propri�t� de l'�l�ment dans la collection</entry>
+
+
<entry><literal>{[aliasname].element.[propertyname]}</literal></entry>
+
+ <entry><literal>NAME as
{coll.element.name}</literal></entry>
+ </row>
+
+ <row>
+ <entry>Toutes les propri�t�s de l'�l�ment dans la
collection</entry>
+
+
<entry><literal>{[aliasname].element.*}</literal></entry>
+
+ <entry><literal>{coll.element.*}</literal></entry>
+ </row>
+
+ <row>
+ <entry>Toutes les propri�t�s de la collection</entry>
+
+ <entry><literal>{[aliasname].*}</literal></entry>
+
+ <entry><literal>{coll.*}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="querysql-namedqueries" revision="3">
+ <title>Requ�tes SQL nomm�es</title>
+
+ <para>
+ Les requ�tes SQL nomm�es peuvent �tre d�finies dans le document de mapping
+ et appel�es exactement de la m�me mani�re qu'un requ�te HQL nomm�e. Dans ce
+ cas, nous <emphasis>n'avons pas besoin</emphasis> d'appeler
<literal>addEntity()</literal>.
+ </para>
+
+ <programlisting><sql-query name="persons">
+ <return alias="person" class="eg.Person"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex}
+ FROM PERSON person
+ WHERE person.NAME LIKE :namePattern
+</sql-query></programlisting>
+
+ <programlisting>List people = sess.getNamedQuery("persons")
+ .setString("namePattern", namePattern)
+ .setMaxResults(50)
+ .list();</programlisting>
+
+ <para>
+ Les �l�ments <literal><return-join></literal> et
+ <literal><load-collection></literal> sont
respectivement utilis�s pour lier
+ des associations et d�finir des requ�tes qui initialisent des collections.
+ </para>
+
+ <programlisting><sql-query name="personsWith">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address"
property="person.mailingAddress"/>
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query></programlisting>
+
+ <para>
+ Une requ�te SQL nomm�e peut retourner une valeur scalaire. Vous devez
+ sp�cifier l'alias de colonne et le type Hibernate utilisant l'�l�ment
+ <literal><return-scalar></literal> :</para>
+
+ <programlisting><sql-query name="mySqlQuery">
+ <return-scalar column="name" type="string"/>
+ <return-scalar column="age" type="long"/>
+ SELECT p.NAME AS name,
+ p.AGE AS age,
+ FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
+</sql-query></programlisting>
+
+ <para>
+ Vous pouvez externaliser les informations de mapping des r�sultats dans un
+ �l�ment <literal><resultset></literal> pour soit les
r�utiliser
+ dans diff�rentes requ�tes nomm�es, soit � travers l'API
+ <literal>setResultSetMapping()</literal>.
+ </para>
+
+ <programlisting><resultset name="personAddress">
+ <return alias="person" class="eg.Person"/>
+ <return-join alias="address"
property="person.mailingAddress"/>
+</resultset>
+
+<sql-query name="personsWith"
resultset-ref="personAddress">
+ SELECT person.NAME AS {person.name},
+ person.AGE AS {person.age},
+ person.SEX AS {person.sex},
+ address.STREET AS {address.street},
+ address.CITY AS {address.city},
+ address.STATE AS {address.state},
+ address.ZIP AS {address.zip}
+ FROM PERSON person
+ JOIN ADDRESS address
+ ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+ WHERE person.NAME LIKE :namePattern
+</sql-query></programlisting>
+
+ <sect2 id="propertyresults">
+ <title>Utilisation de return-property pour sp�cifier explicitement les noms
des colonnes/alias</title>
+
+ <para>
+ Avec <literal><return-property></literal> vous pouvez
explicitement dire
+ � Hibernate quels alias de colonne utiliser, plutot que d'employer la
syntaxe
+ <literal>{}</literal> pour laisser Hibernate injecter ses propres
alias.
+ </para>
+
+ <programlisting><sql-query name="mySqlQuery">
+ <return alias="person" class="eg.Person">
+ <return-property name="name" column="myName"/>
+ <return-property name="age" column="myAge"/>
+ <return-property name="sex" column="mySex"/>
+ </return>
+ SELECT person.NAME AS myName,
+ person.AGE AS myAge,
+ person.SEX AS mySex,
+ FROM PERSON person WHERE person.NAME LIKE :name
+</sql-query>
+</programlisting>
+
+ <para>
+ <literal><return-property></literal> fonctionne aussi
avec de
+ multiple colonnes. Cela r�sout une limitation de la syntaxe
<literal>{}</literal>
+ qui ne peut pas permettre une bonne granularit� des propri�t�s multi-colonnes.
+ </para>
+
+ <programlisting><sql-query
name="organizationCurrentEmployments">
+ <return alias="emp" class="Employment">
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ <return-property name="endDate"
column="myEndDate"/>
+ </return>
+ SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},
+ STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
+ REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY
+ FROM EMPLOYMENT
+ WHERE EMPLOYER = :id AND ENDDATE IS NULL
+ ORDER BY STARTDATE ASC
+</sql-query></programlisting>
+
+ <para>
+ Notez que dans cet exemple nous avons utilis�
<literal><return-property></literal>
+ en combinaison avec la syntaxe <literal>{}</literal> pour
l'injection. Cela autorise les
+ utilisateurs � choisir comment ils veulent r�f�rencer les colonnes et les
propri�t�s.
+ </para>
+
+ <para>
+ Si votre mapping a un discriminant vous devez utiliser
+ <literal><return-discriminator></literal> pour
sp�cifier la colonne
+ discriminante.
+ </para>
+ </sect2>
+
+ <sect2 id="sp_query" revision="1">
+ <title>Utilisation de proc�dures stock�es pour les requ�tes</title>
+
+ <para>
+ Hibernate 3 introduit le support des requ�tes via proc�dures stock�es et les
fonctions.
+ La documentation suivante est valable pour les deux.
+ Les proc�dures stock�es/fonctions doivent retourner l'ensemble de r�sultats
en tant que
+ premier param�tre sortant (NdT: "out-parameter") pour �tre capable de
fonctionner
+ avec Hibernate. Un exemple d'une telle proc�dure stock�e en Oracle 9 et
+ version sup�rieure :
+ </para>
+
+ <programlisting>CREATE OR REPLACE FUNCTION selectAllEmployments
+ RETURN SYS_REFCURSOR
+AS
+ st_cursor SYS_REFCURSOR;
+BEGIN
+ OPEN st_cursor FOR
+ SELECT EMPLOYEE, EMPLOYER,
+ STARTDATE, ENDDATE,
+ REGIONCODE, EID, VALUE, CURRENCY
+ FROM EMPLOYMENT;
+ RETURN st_cursor;
+ END;</programlisting>
+
+ <para>Pour utiliser cette requ�te dans Hibernate vous avez besoin de la
mapper via une requ�te nomm�e.</para>
+
+ <programlisting><sql-query name="selectAllEmployees_SP"
callable="true">
+ <return alias="emp" class="Employment">
+ <return-property name="employee"
column="EMPLOYEE"/>
+ <return-property name="employer"
column="EMPLOYER"/>
+ <return-property name="startDate"
column="STARTDATE"/>
+ <return-property name="endDate"
column="ENDDATE"/>
+ <return-property name="regionCode"
column="REGIONCODE"/>
+ <return-property name="id" column="EID"/>
+ <return-property name="salary">
+ <return-column name="VALUE"/>
+ <return-column name="CURRENCY"/>
+ </return-property>
+ </return>
+ { ? = call selectAllEmployments() }
+</sql-query></programlisting>
+
+ <para>
+ Notez que les proc�dures stock�es retournent, pour le moment, seulement des
+ scalaires et des entit�s.
<literal><return-join></literal> et
+ <literal><load-collection></literal> ne sont pas
support�s.
+ </para>
+
+ <sect3 id="querysql-limits-storedprocedures"
revision="1">
+ <title>R�gles/limitations lors de l'utilisation des proc�dures
stock�es</title>
+
+ <para>
+ Pur utiliser des proc�dures stock�es avec Hibernate, les proc�dures doivent
+ suivre certaines r�gles. Si elles ne suivent pas ces r�gles, elles ne sont
pas
+ utilisables avec Hibernate. Si vous voulez encore utiliser ces proc�dures
vous
+ devez les ex�cuter via <literal>session.connection()</literal>.
Les r�gles
+ sont diff�rentes pour chaque base de donn�es, puisque les vendeurs de base
+ de donn�es ont des s�mantiques/syntaxes diff�rentes pour les proc�dures
stock�es.
+ </para>
+
+ <para>Les requ�tes de proc�dures stock�es ne peuvent pas �tre pagin�es
avec
+
<literal>setFirstResult()/setMaxResults()</literal>.</para>
+
+ <para>Pour Oracle les r�gles suivantes s'appliquent :</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ La proc�dure doit retourner un ensemble de r�sultats. Le
+ prmeier param�tre d'une proc�dure doit �tre un
<literal>OUT</literal>
+ qui retourne un ensemble de r�sultats. Ceci est fait en
+ retournant un <literal>SYS_REFCURSOR</literal> dans Oracle 9
ou 10. Dans
+ Oracle vous avez besoin de d�finir un type <literal>REF
CURSOR</literal>.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>Pour Sybase ou MS SQL server les r�gles suivantes s'appliquent
:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>La proc�dure doit retourner un ensemble de r�sultats. Notez que
comme
+ ces serveurs peuvent retourner de multiples ensembles de r�sultats et mettre
� jour
+ des compteurs, Hibernate it�rera les r�sultats et prendra le premier r�sultat
qui est
+ un ensemble de r�sultat comme valeur de retour. Tout le reste sera
ignor�.</para>
+ </listitem>
+
+ <listitem>
+ <para>Si vous pouvez activer <literal>SET NOCOUNT
ON</literal> dans votre proc�dure,
+ elle sera probablement plus efficace, mais ce n'est pas une
obligation.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="querysql-cud">
+ <title>SQL personnalis� pour cr�er, mettre � jour et effacer</title>
+
+ <para>
+ Hibernate3 peut utiliser des expression SQL personnalis�es pour des op�rations de
cr�ation,
+ de mise � jour, et de suppression. Les objets persistants les classes et les
collections
+ dans Hibernate contiennent d�j� un ensemble de cha�nes de caract�res g�n�r�es
lors de la
+ configuration (insertsql, deletesql, updatesql, etc). Les tages de mapping
+ <literal><sql-insert></literal>,
+ <literal><sql-delete></literal>, et
+ <literal><sql-update></literal> surchargent ces cha�nes de
caract�res :</para>
+
+ <programlisting><class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ?
)</sql-insert>
+ <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE
ID=?</sql-update>
+ <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
+</class></programlisting>
+
+ <para>Le SQL est directement ex�cut� dans votre base de donn�es, donc vous �tes
libre d'utiliser
+ le dialecte que vous souhaitez. Cela r�duira bien s�r la portabilit� de votre
mapping si vous
+ utilisez du SQL sp�cifique � votre base de donn�es.</para>
+
+ <para>Les proc�dures stock�es sont support�es si l'attribut
<literal>callable</literal> est param�tr� :</para>
+
+ <programlisting><class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <sql-insert callable="true">{call createPerson (?,
?)}</sql-insert>
+ <sql-delete callable="true">{? = call deletePerson
(?)}</sql-delete>
+ <sql-update callable="true">{? = call updatePerson (?,
?)}</sql-update>
+</class></programlisting>
+
+ <para>L'ordre des param�tres positionnels est actuellement vital, car ils
doivent �tre dans la
+ m�me s�quence qu'Hibernate les attend.</para>
+
+ <para>
+ Vous pouvez voir l'ordre attendu en activant les journaux de debug pour le
+ niveau <literal>org.hibernate.persister.entity</literal> level. Avec
ce niveau activ�,
+ Hibernate imprimera le SQL statique qui est utilis� pour cr�er, mettre � jour,
+ supprimer, etc. des entit�s. (Pour voir la s�quence attendue, rappelez-vous de ne
pas
+ inclure votre SQL personnalis� dans les fichiers de mapping de mani�re �
surcharger le
+ SQL statique g�n�r� par Hibernate.)</para>
+
+ <para>Les proc�dures stock�es sont dans la plupart des cas (lire : il vaut
mieux le faire)
+ requises pour retourner le nombre de lignes ins�r�es/mises � jour/supprim�es,
puisque
+ Hibernate fait quelques v�rifications de succ�s lors de l'ex�cution de
l'expression.
+ Hibernate inscrit toujours la premi�re expression comme un param�tre de sortie
num�rique pour les
+ op�rations CUD :</para>
+
+ <programlisting>CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname
IN VARCHAR2)
+ RETURN NUMBER IS
+BEGIN
+
+ update PERSON
+ set
+ NAME = uname,
+ where
+ ID = uid;
+
+ return SQL%ROWCOUNT;
+
+END updatePerson;</programlisting>
+ </sect1>
+
+ <sect1 id="querysql-load">
+ <title>SQL personnalis� pour le chargement</title>
+
+ <para>Vous pouvez aussi d�clarer vos propres requ�tes SQL (ou HQL) pour le
chargement d'entit� :</para>
+
+ <programlisting><sql-query name="person">
+ <return alias="pers" class="Person"
lock-mode="upgrade"/>
+ SELECT NAME AS {pers.name}, ID AS {pers.id}
+ FROM PERSON
+ WHERE ID=?
+ FOR UPDATE
+</sql-query></programlisting>
+
+ <para>Ceci est juste une d�claration de requ�te nomm�e, comme vu plus t�t. Vous
pouvez r�f�rencer
+ cette requ�te nomm�e dans un mapping de classe :</para>
+
+ <programlisting><class name="Person">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name" not-null="true"/>
+ <loader query-ref="person"/>
+</class></programlisting>
+
+ <para>Ceci fonctionne m�me avec des proc�dures stock�es.</para>
+
+ <para>Vous pouvez m�me d�finir une requ�te pour le chargement d'une
collection :</para>
+
+ <programlisting><set name="employments"
inverse="true">
+ <key/>
+ <one-to-many class="Employment"/>
+ <loader query-ref="employments"/>
+</set></programlisting>
+
+ <programlisting><sql-query name="employments">
+ <load-collection alias="emp"
role="Person.employments"/>
+ SELECT {emp.*}
+ FROM EMPLOYMENT emp
+ WHERE EMPLOYER = :id
+ ORDER BY STARTDATE ASC, EMPLOYEE ASC
+</sql-query></programlisting>
+
+ <para>Vous pourriez m�me d�finir un chargeur d'entit� qui charge une
collection par jointure :</para>
+
+ <programlisting><sql-query name="person">
+ <return alias="pers" class="Person"/>
+ <return-join alias="emp"
property="pers.employments"/>
+ SELECT NAME AS {pers.*}, {emp.*}
+ FROM PERSON pers
+ LEFT OUTER JOIN EMPLOYMENT emp
+ ON pers.ID = emp.PERSON_ID
+ WHERE ID=?
+</sql-query></programlisting>
+ </sect1>
+</chapter>
\ No newline at end of file
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/session_api.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/session_api.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/session_api.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/session_api.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,1226 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<chapter id="objectstate">
+ <title>Travailler avec des objets</title>
+ <para>
+ Hibernate est une solution de mapping objet/relationnel compl�te qui ne masque
pas
+ seulement au d�velopppeur les d�tails du syst�me de gestion de base de donn�es
sous-jacent,
+ mais offre aussi <emphasis>la gestion d'�tat</emphasis> des
objets. C'est, contrairement
+ � la gestion de <literal>statements</literal> SQL dans les couches de
persistance
+ habituelles JDBC/SQL, une vue orient�e objet tr�s naturelle de la persistance
dans les
+ applications Java.
+ </para>
+
+ <para>
+ En d'autres mots, les d�veloppeurs d'applications Hibernate devrait
toujours
+ r�fl�chir � <emphasis>l'�tat</emphasis> de leurs objets, et pas
n�cessairement �
+ l'ex�cution des expressions SQL. Cette part est prise en charge pas Hibernate
et
+ seulement importante pour les d�veloppeurs d'applications lors du r�glage de
la
+ performance de leur syst�me.
+ </para>
+
+ <sect1 id="objectstate-overview">
+ <title>�tats des objets Hibernate</title>
+
+ <para>
+ Hibernate d�finit et comprend les �tats suivants :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>�ph�m�re</emphasis> (NdT : transient) - un
objet est �ph�m�re s'il a juste
+ �t� instanci� en utilisant l'op�rateur
<literal>new</literal>. Il n'a aucune
+ repr�sentation persistante dans la base de donn�es et aucune valeur
d'identifiant
+ n'a �t� assign�e. Les instances �ph�m�res seront d�truites par le
ramasse-miettes
+ si l'application n'en conserve aucune r�f�rence. Utilisez la
<literal>Session</literal>
+ d'Hibernate pour rendre un objet persistant (et laisser Hibernate
s'occuper des
+ expressions SQL qui ont besoin d'�tre ex�cut�es pour cette
transistion).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Persistant</emphasis> - une instance
persistante a une repr�sentation dans la
+ base de donn�es et une valeur d'identifiant. Elle pourrait avoir
juste �t� sauvegard�e
+ ou charg�e, pourtant, elle est par d�finition dans la port�e
d'une <literal>Session</literal>.
+ Hibernate d�tectera n'importe quels changements effectu�s sur un
objet dans l'�tat
+ persistant et synchronisera l'�tat avec la base de donn�es lors
de la fin l'unit� de travail.
+ Les d�veloppeurs n'ex�cutent pas d'expressions
<literal>UPDATE</literal> ou
+ <literal>DELETE</literal> manuelles lorsqu'un objet
devrait �tre rendu �ph�m�re.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>D�tach�</emphasis> - une instance d�tach�e est
un objet qui a �t� persistant,
+ mais dont sa <literal>Session</literal> a �t� ferm�e. La
r�f�rence � l'objet est
+ encore valide, bien s�r, et l'instance d�tach�e pourrait m�me
�tre modifi�e dans cet
+ �tat. Une instance d�tach�e peut �tre r�attach�e � une nouvelle
<literal>Session</literal>
+ plus tard dans le temps, la rendant (et toutes les modifications
avec) de nouveau persistante.
+ Cette fonctionnalit� rend possible un mod�le de programmation pour de
longues unit�s de travail
+ qui requi�rent un temps de r�flexion de l'utilisateur. Nous les
appelons des <emphasis>conversations</emphasis>,
+ c'est-�-dire une unit� de travail du point de vue de
l'utilisateur.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Nous alons maintenant dicuster des �tats et des transitions d'�tat (et
des m�thodes
+ d'Hibernate qui d�clenchent une transition) plus en d�tails.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-makingpersistent" revision="1">
+ <title>Rendre des objets persistants</title>
+
+ <para>
+ Les instances nouvellement instanci�es d'une classe persistante sont
consid�r�es
+ <emphasis>�ph�m�res</emphasis> par Hibernate. Nous pouvons rendre
une instance
+ �ph�m�re <emphasis>persistante</emphasis> en l'associant avec
une session :
+ </para>
+
+ <programlisting><![CDATA[DomesticCat fritz = new DomesticCat();
+fritz.setColor(Color.GINGER);
+fritz.setSex('M');
+fritz.setName("Fritz");
+Long generatedId = (Long) sess.save(fritz);]]></programlisting>
+
+ <para>
+ Si <literal>Cat</literal> a un identifiant g�n�r�,
l'identifiant est g�n�r� et assign�
+ au <literal>cat</literal> lorsque
<literal>save()</literal> est appel�e. Si <literal>Cat</literal>
+ a un identifiant <literal>assigned</literal>, ou une clef
compos�e, l'identifiant
+ devrait �tre assign� � l'instance de <literal>cat</literal>
avant d'appeler <literal>save()</literal>.
+ Vous pouvez aussi utiliser <literal>persist()</literal> � la
place de<literal>save()</literal>,
+ avec la s�mantique d�finie plus t�t dans le brouillon d'EJB3.
+ </para>
+
+ <para>
+ Alternativement, vous pouvez assigner l'identifiant en utilisant une
version
+ surcharg�e de <literal>save()</literal>.
+ </para>
+
+<programlisting><![CDATA[DomesticCat pk = new DomesticCat();
+pk.setColor(Color.TABBY);
+pk.setSex('F');
+pk.setName("PK");
+pk.setKittens( new HashSet() );
+pk.addKitten(fritz);
+sess.save( pk, new Long(1234) );]]></programlisting>
+
+ <para>
+ Si l'objet que vous rendez persistant a des objets associ�s (par
exemple,
+ la collection <literal>kittens</literal> dans l'exemple
pr�c�dent), ces objets
+ peuvent �tre rendus persistants dans n'importe quel ordre que vous
souhaitez
+ � moins que vous ayez une contrainte <literal>NOT NULL</literal>
sur la
+ colonne de la clef �trang�re. Il n'y a jamais de risque de violer une
+ contrainte de clef �trang�re. Cependant, vous pourriez violer une contrainte
+ <literal>NOT NULL</literal> si vous appeliez
<literal>save()</literal> sur
+ les objets dans le mauvais ordre.
+ </para>
+
+ <para>
+ Habituellement, vous ne vous pr�occupez pas de ce d�tail, puisque vous
+ utiliserez tr�s probablement la fonctionnalit� de
<emphasis>persistance
+ transitive</emphasis> d'Hibernate pour sauvegarder les objets
associ�s
+ automatiquement. Alors, m�me les violations de contrainte <literal>NOT
NULL</literal>
+ n'ont plus lieu - Hibernate prendra soin de tout. La persistance
transitive est
+ trait�e plus loin dans ce chapitre.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-loading">
+ <title>Chargement d'un objet</title>
+
+ <para>
+ Les m�thodes <literal>load()</literal> de
<literal>Session</literal> vous donnent
+ un moyen de r�cup�rer une instance persistante si vous connaissez d�j� son
identifiant.
+ <literal>load()</literal> prend un objet de classe et chargera
l'�tat dans une instance
+ nouvellement instanci�e de cette classe, dans un �tat persistant.
+ </para>
+
+ <programlisting><![CDATA[Cat fritz = (Cat) sess.load(Cat.class,
generatedId);]]></programlisting>
+
+<programlisting><![CDATA[// vous avez besoin d'envelopper les identiants
primitifs
+long pkId = 1234;
+DomesticCat pk = (DomesticCat) sess.load( Cat.class, new Long(pkId)
);]]></programlisting>
+
+ <para>
+ Alternativement, vous pouvez charger un �tat dans une instance donn�e :
+ </para>
+
+<programlisting><![CDATA[Cat cat = new DomesticCat();
+// load pk's state into cat
+sess.load( cat, new Long(pkId) );
+Set kittens = cat.getKittens();]]></programlisting>
+
+ <para>
+ Notez que <literal>load()</literal> l�vera une exception
irr�cup�rable s'il
+ n'y a pas de ligne correspondante dans la base de donn�es. Si la classe
est mapp�e
+ avec un proxy, <literal>load()</literal> retourne juste un proxy
non initialis� et
+ n'acc�de en fait pas � la base de donn�es jusqu'� ce que vous
invoquiez une
+ m�thode du proxy. Ce comportement est tr�s utile si vous souhaitez cr�er
+ une association vers un objet sans r�ellement le charger � partir de la base
de
+ donn�es. Cela permet aussi � de multiples instances d'�tre charg�es comme
un lot
+ si <literal>batch-size</literal> est d�fini pour le mapping de la
classe.
+ </para>
+
+ <para>
+ Si vous n'�tes pas certain qu'une ligne correspondante existe, vous
devriez
+ utiliser la m�thode <literal>get()</literal>, laquelle acc�de �
la base de
+ donn�es imm�diatement et retourne null s'il n'y a pas de ligne
correspondante.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id);
+if (cat==null) {
+ cat = new Cat();
+ sess.save(cat, id);
+}
+return cat;]]></programlisting>
+
+ <para>
+ Vous pouvez m�me charger un objet en employant un <literal>SELECT ...
FOR UPDATE</literal> SQL,
+ en utilisant un <literal>LockMode</literal>. Voir la
documentation de l'API pour plus d'informations.
+ </para>
+
+ <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id,
LockMode.UPGRADE);]]></programlisting>
+
+ <para>
+ Notez que n'importe quelles instances associ�es ou collections contenues
+ <emphasis>ne sont pas</emphasis> s�lectionn�es par
<literal>FOR UPDATE</literal>,
+ � moins que vous ne d�cidiez de sp�cifier <literal>lock</literal>
ou <literal>all</literal>
+ en tant que style de cascade pour l'association.
+ </para>
+
+ <para>
+ Il est possible de re-charger un objet et toutes ses collections �
n'importe quel moment,
+ en utilisant la m�thode <literal>refresh()</literal>. C'est
utile lorsque des "triggers" de
+ base de donn�es sont utilis�s pour initiliser certains propri�t�s de
l'objet.
+ </para>
+
+ <programlisting><![CDATA[sess.save(cat);
+sess.flush(); //force the SQL INSERT
+sess.refresh(cat); //re-read the state (after the trigger
executes)]]></programlisting>
+
+ <para>
+ Une question importante appara�t g�n�ralement � ce point : combien (NdT : de
donn�es) Hibernate
+ charge-t-il de la base de donn�es et combient de
<literal>SELECT</literal>s utilisera-t-il ?
+ Cela d�pent de la <emphasis>strat�gie de r�cup�ration</emphasis>
et cela est expliqu� dans
+ <xref linkend="performance-fetching"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-querying" revision="1">
+ <title>Requ�tage</title>
+
+ <para>
+ Si vous ne connaissez par les identifiants des objets que vous recherchez,
vous
+ avez besoin d'une requ�te. Hibernate supporte un langage de requ�tes
orient�es objet
+ facile � utiliser mais puissant. Pour la cr�ation de requ�tes par
programmation,
+ Hibernate supporte une fonction de requ�tage sophistiqu� Criteria et Example
(QBC et QBE).
+ Vous pouvez aussi exprimez votre requ�te dans le SQL natif de votre base de
donn�es,
+ avec un support optionnel d'Hibernate pour la conversion des ensembles de
r�sultats en
+ objets.
+ </para>
+
+ <sect2 id="objectstate-querying-executing">
+ <title>Ex�cution de requ�tes</title>
+
+ <para>
+ Les requ�tes HQL et SQL natives sont repr�sent�es avec une instance de
<literal>org.hibernate.Query</literal>.
+ L'interface offre des m�thodes pour la liaison des param�tres, la
gestion des ensembles de resultats, et pour
+ l'ex�cution de la requ�te r�elle. Vous obtenez toujours une
<literal>Query</literal> en utilisant la
+ <literal>Session</literal> courante :
+ </para>
+
+ <programlisting><![CDATA[List cats = session.createQuery(
+ "from Cat as cat where cat.birthdate < ?")
+ .setDate(0, date)
+ .list();
+
+List mothers = session.createQuery(
+ "select mother from Cat as cat join cat.mother as mother where cat.name =
?")
+ .setString(0, name)
+ .list();
+
+List kittens = session.createQuery(
+ "from Cat as cat where cat.mother = ?")
+ .setEntity(0, pk)
+ .list();
+
+Cat mother = (Cat) session.createQuery(
+ "select cat.mother from Cat as cat where cat = ?")
+ .setEntity(0, izi)
+ .uniqueResult();]]></programlisting>
+
+ <para>
+ Une requ�te est g�n�ralement ex�cut�e en invoquant
<literal>list()</literal>,
+ le r�sultat de la requ�te sera charg�e compl�tement dans une collection
en m�moire.
+ Les intances d'entit�s recup�r�es par une requ�te sont dans un �tat
persistant.
+ La m�thode <literal>uniqueResult()</literal> offre un
raccourci si vous
+ savez que votre requ�te retournera seulement un seul objet.
+ </para>
+
+ <sect3 id="objectstate-querying-executing-iterate">
+ <title>It�ration de r�sultats</title>
+
+ <para>
+ Occasionnellement, vous pourriez �tre capable d'obtenir de
meilleures
+ performances en ex�cutant la requ�te avec la m�thode
<literal>iterate()</literal>.
+ Ce sera g�n�ralement seulement le cas si vous esp�rez que les
intances r�elles
+ d'entit� retourn�es par la requ�te soient d�j� charg�es dans la
session ou le
+ cache de second niveau. Si elles ne sont pas cach�es,
<literal>iterate()</literal>
+ sera plus lent que <literal>list()</literal> et pourrait
n�cessiter plusieurs
+ acc�s � la base de donn�es pour une simple requ�te, g�n�ralement
<emphasis>1</emphasis>
+ pour le select initial qui retourne seulement les identifiants, et
<emphasis>n</emphasis>
+ selects suppl�mentaires pour initialiser les instances r�elles.
+ </para>
+
+ <programlisting><![CDATA[// fetch ids
+Iterator iter = sess.createQuery("from eg.Qux q order by
q.likeliness").iterate();
+while ( iter.hasNext() ) {
+ Qux qux = (Qux) iter.next(); // fetch the object
+ // something we couldnt express in the query
+ if ( qux.calculateComplicatedAlgorithm() ) {
+ // delete the current instance
+ iter.remove();
+ // dont need to process the rest
+ break;
+ }
+}]]></programlisting>
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-tuples">
+ <title>Requ�tes qui retournent des tuples</title>
+
+ <para>
+ Les requ�tes d'Hibernate retournent parfois des tuples
d'objets, auquel cas chaque tuple
+ est retourn� comme un tableau :
+ </para>
+
+ <programlisting><![CDATA[Iterator kittensAndMothers =
sess.createQuery(
+ "select kitten, mother from Cat kitten join kitten.mother mother")
+ .list()
+ .iterator();
+
+while ( kittensAndMothers.hasNext() ) {
+ Object[] tuple = (Object[]) kittensAndMothers.next();
+ Cat kitten = (Cat) tuple[0];
+ Cat mother = (Cat) tuple[1];
+ ....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scalar"
revision="1">
+ <title>R�sultats scalaires</title>
+
+ <para>
+ Des requ�tes peuvent sp�cifier une propri�t� d'une classe dans la
clause <literal>select</literal>.
+ Elles peuvent m�me appeler des fonctions d'aggr�gat SQL. Les
propri�t�s ou les aggr�gats sont
+ consid�r�s comme des r�sultats "scalaires" (et pas des
entit�s dans un �tat persistant).
+ </para>
+
+ <programlisting><![CDATA[Iterator results = sess.createQuery(
+ "select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
+ "group by cat.color")
+ .list()
+ .iterator();
+
+while ( results.hasNext() ) {
+ Object[] row = (Object[]) results.next();
+ Color type = (Color) row[0];
+ Date oldest = (Date) row[1];
+ Integer count = (Integer) row[2];
+ .....
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-parameters">
+ <title>Lier des param�tres</title>
+
+ <para>
+ Des m�thodes de <literal>Query</literal> sont fournies
pour lier des
+ valeurs � des param�tres nomm�s ou � des param�tres de style JDBC
<literal>?</literal>.
+ <emphasis>Contrairement � JDBC, les num�ros des param�tres
d'Hibernate commencent � z�ro.</emphasis>
+ Les param�tres nomm�s sont des identifiants de la forme
<literal>:nom</literal> dans la cha�ne de
+ caract�res de la requ�te. Les avantages des param�tres nomm�s sont :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ les param�tres nomm�s sont insensibles � l'ordre de leur
place dans la cha�ne
+ de la requ�te
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ils peuvent appara�tre plusieurs fois dans la m�me requ�te
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ils sont auto-document�s
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <programlisting><![CDATA[//param�tre nomme (pr�f�r�)
+Query q = sess.createQuery("from DomesticCat cat where cat.name = :name");
+q.setString("name", "Fritz");
+Iterator cats = q.iterate();]]></programlisting>
+
+ <programlisting><![CDATA[//param�tre positionnel
+Query q = sess.createQuery("from DomesticCat cat where cat.name = ?");
+q.setString(0, "Izi");
+Iterator cats = q.iterate();]]></programlisting>
+
+ <programlisting><![CDATA[//liste de param�tres nomm�s
+List names = new ArrayList();
+names.add("Izi");
+names.add("Fritz");
+Query q = sess.createQuery("from DomesticCat cat where cat.name in
(:namesList)");
+q.setParameterList("namesList", names);
+List cats = q.list();]]></programlisting>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-pagination">
+ <title>Pagination</title>
+
+ <para>
+ Si vous avez besoin de sp�cifier des liens sur votre ensemble de
r�sultats (le nombre
+ maximum de lignes que vous voulez r�cup�rez et/ou la premi�re ligne
que vous voulez r�cup�rer)
+ vous devriez utiliser des m�thodes de l'interface
<literal>Query</literal> :
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.createQuery("from
DomesticCat cat");
+q.setFirstResult(20);
+q.setMaxResults(10);
+List cats = q.list();]]></programlisting>
+
+ <para>
+ Hibernate sait comment traduite cette requ�te de limite en SQL natif
pour votre SGBD.
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-scrolling">
+ <title>It�ration "scrollable"</title>
+
+ <para>
+ Si votre connecteur JDBC supporte les
<literal>ResultSet</literal>s "scrollables",
+ l'interface <literal>Query</literal> peut �tre
utilis�e pour obtenir un objet
+ <literal>ScrollableResults</literal>, lequel permet une
navigation flexible dans les
+ r�sultats de la requ�te.
+ </para>
+
+ <programlisting><![CDATA[Query q = sess.createQuery("select
cat.name, cat from DomesticCat cat " +
+ "order by cat.name");
+ScrollableResults cats = q.scroll();
+if ( cats.first() ) {
+
+ // trouve le premier nom sur chaque page d'une liste alphab�tique de noms de
chats
+ firstNamesOfPages = new ArrayList();
+ do {
+ String name = cats.getString(0);
+ firstNamesOfPages.add(name);
+ }
+ while ( cats.scroll(PAGE_SIZE) );
+
+ // Maintenant, obtiens la premi�re page de chats
+ pageOfCats = new ArrayList();
+ cats.beforeFirst();
+ int i=0;
+ while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1)
);
+
+}
+cats.close()]]></programlisting>
+
+ <para>
+ Notez qu'une connexion ouverte (et un curseur) est requise pour
cette fonctionnalit�,
+ utilisez
<literal>setMaxResult()</literal>/<literal>setFirstResult()</literal>
si vous
+ avez besoin d'une fonctionnalit� de pagination hors ligne.
+ </para>
+
+ </sect3>
+
+ <sect3 id="objectstate-querying-executing-named">
+ <title>Externaliser des requ�tes nomm�es</title>
+
+ <para>
+ Vous pouvez aussi d�finir des requ�tes nomm�es dans le document de
mapping.
+ (Souvenez-vous d'utiliser une section
<literal>CDATA</literal> si votre requ�te
+ contient des caract�res qui pourraient �tre interpr�t�s comme des
�l�ments XML.)
+ </para>
+
+ <programlisting><![CDATA[<query
name="eg.DomesticCat.by.name.and.minimum.weight"><![CDATA[
+ from eg.DomesticCat as cat
+ where cat.name = ?
+ and cat.weight > ?
+] ]></query>]]></programlisting>
+
+ <para>
+ La liaison de param�tres et l'ex�cution sont fait par
programmation :
+ </para>
+
+ <programlisting><![CDATA[Query q =
sess.getNamedQuery("eg.DomesticCat.by.name.and.minimum.weight");
+q.setString(0, name);
+q.setInt(1, minWeight);
+List cats = q.list();]]></programlisting>
+
+ <para>
+ Notez que le code r�el du programme est ind�pendant du langage de
requ�te qui est
+ utilis�, vous pouvez aussi d�finir des requ�tes SQL nativez dans les
m�ta-donn�es, ou
+ migrer des requ�tes existantes vers Hibernate en les pla�ant dans les
fichiers de mapping.
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="objectstate-filtering" revision="1">
+ <title>Filtrer des collections</title>
+ <para>
+ Un <emphasis>filtre</emphasis> de collection est un type
sp�cial de requ�te qui peut �tre
+ appliqu� � une collection persistante ou � un tableau. La cha�ne de
requ�te peut se r�f�rer �
+ <literal>this</literal>, correspondant � l'�l�ment de la
collection courant.
+ </para>
+
+ <programlisting><![CDATA[Collection blackKittens =
session.createFilter(
+ pk.getKittens(),
+ "where this.color = ?")
+ .setParameter( Color.BLACK, Hibernate.custom(ColorUserType.class) )
+ .list()
+);]]></programlisting>
+
+ <para>
+ La collection retourn�e est consid�r�e comme un bag, et c'est une
copie de la
+ collection donn�e. La collection originale n'est pas modifi�e
(c'est contraire
+ � l'implication du nom "filtre"; mais coh�rent avec le
comportement attendu).
+ </para>
+
+ <para>
+ Observez que les filtres ne n�cessitent pas une clause
<literal>from</literal> (bien qu'ils
+ puissent en avoir une si besoin est). Les filtres ne sont pas limit�s �
retourner des
+ �l�ments de la collection eux-m�mes.
+ </para>
+
+ <programlisting><![CDATA[Collection blackKittenMates =
session.createFilter(
+ pk.getKittens(),
+ "select this.mate where this.color = eg.Color.BLACK.intValue")
+ .list();]]></programlisting>
+
+ <para>
+ M�me une requ�te de filtre vide est utile, par exemple pour charger un
sous-ensemble
+ d'�l�ments dans une �norme collection :
+ </para>
+
+ <programlisting><![CDATA[Collection tenKittens =
session.createFilter(
+ mother.getKittens(), "")
+ .setFirstResult(0).setMaxResults(10)
+ .list();]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="objecstate-querying-criteria" revision="1">
+ <title>Requ�tes Criteria</title>
+
+ <para>
+ HQL est extr�mement puissant mais certains d�veloppeurs pr�f�rent
construire des
+ requ�tes dynamiquement, en utilisant l'API orient�e objet, plut�t que
construire
+ des cha�nes de requ�tes. Hibernate fournit une API intuitive de requ�te
<literal>Criteria</literal>
+ pour ces cas :
+ </para>
+
+ <programlisting><![CDATA[Criteria crit =
session.createCriteria(Cat.class);
+crit.add( Restrictions.eq( "color", eg.Color.BLACK ) );
+crit.setMaxResults(10);
+List cats = crit.list();]]></programlisting>
+
+ <para>
+ Les APIs <literal>Criteria</literal> et
<literal>Example</literal> associ� sont
+ trait�es plus en d�tail dans <xref
linkend="querycriteria"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="objectstate-querying-nativesql"
revision="2">
+ <title>Requ�tes en SQL natif</title>
+
+ <para>
+ Vous pouvez exprimer une requ�te en SQL, en utilisant
<literal>createSQLQuery()</literal>
+ et laisser Hibernate s'occuper du mapping des r�sultats vers des
objets. Notez que vous
+ pouvez n'importe quand appeler
<literal>session.connection()</literal> et utiliser
+ directement la <literal>Connection</literal> JDBC. Si vous
choisissez d'utiliser
+ l'API Hibernate, vous devez mettre les alias SQL entre accolades :
+ </para>
+
+ <programlisting><![CDATA[List cats =
session.createSQLQuery("SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list();]]></programlisting>
+
+ <programlisting><![CDATA[List cats = session.createSQLQuery(
+ "SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, " +
+ "{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... " +
+ "FROM CAT {cat} WHERE ROWNUM<10")
+ .addEntity("cat", Cat.class)
+.list()]]></programlisting>
+
+ <para>
+ Les requ�tes SQL peuvent contenir des param�tres nomm�s et positionnels,
comme des
+ requ�tes Hibernate. Plus d'informations � propos des requ�tes SQL
natives dans Hibernate
+ peuvent �tre trouv�es dans <xref linkend="querysql"/>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="objectstate-modifying" revision="1">
+ <title>Modifier des objets persistants</title>
+
+ <para>
+ Les <emphasis>instances persistantes transactionnelles</emphasis>
(c'est-�-dire des objets
+ charg�s, sauvegard�s, cr��s ou requ�t�s par la
<literal>Session</literal>) peuvent �tre
+ manipul�es par l'application et n'importe quel changement vers
l'�tat persistant sera
+ persist� lorsque la <literal>Session</literal> est
<emphasis>"flush�e"</emphasis> (trait�
+ plus tard dans ce chapitre). Il n'y a pas besoin d'appeler une
m�thode particuli�re
+ (comme <literal>update()</literal>, qui a un but diff�rent) pour
rendre vos modifications
+ persistantes. Donc la mani�re la plus directe de mettre � jour l'�tat
d'un objet est de
+ le charger avec <literal>load()</literal>, et puis le manipuler
directement, tant que la
+ <literal>Session</literal> est ouverte :
+ </para>
+
+ <programlisting><![CDATA[DomesticCat cat = (DomesticCat) sess.load(
Cat.class, new Long(69) );
+cat.setName("PK");
+sess.flush(); // changes to cat are automatically detected and
persisted]]></programlisting>
+
+ <para>
+ Parfois ce mod�le de programmation est inefficace puisqu'il n�cessiterait
un
+ <literal>SELECT</literal> SQL (pour charger l'objet) et un
<literal>UPDATE</literal>
+ SQL (pour persister son �tat mis � jour) dans la m�me session. Aussi
Hibernate offre
+ une autre approche, en utilisant des instances d�tach�es.
+ </para>
+
+ <para>
+ <emphasis>Notez que Hibernate n'offre par sa propre API pour
l'ex�cution directe
+ d'expressions <literal>UPDATE</literal> ou
<literal>DELETE</literal>. Hibernate
+ est un service de <emphasis>gestion d'�tat</emphasis>, vous
n'avez pas � penser
+ aux <emphasis>expressions</emphasis> pour l'utiliser. JDBC
est une API parfaite
+ pour ex�cuter des expressions SQL, vous pouvez obtenir une
<literal>Connection</literal>
+ JDBC n'importe quand en appelant
<literal>session.connection()</literal>. En outre,
+ la notion d'op�rations de masse entre en conflit avec le mapping
objet/relationnel
+ pour les applications orient�es processus de transactions en ligne. Les
futures
+ versions d'Hibernate peuvent cependant fournir des fonctions
d'op�ration de masse.
+ Voir <xref linkend="batch"/> pour les astuces possibles
d'op�rations group�es.</emphasis>
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-detached" revision="2">
+ <title>Modifier des objets d�tach�s</title>
+
+ <para>
+ Beaucoup d'applications ont besoin de r�cup�rer un objet dans une
transaction,
+ l'envoyer � la couche interfac�e avec l'utilisateur pour les
manipulations, puis
+ sauvegarder les changements dans une nouvelle transaction. Les applications
+ qui utilisent cette approche dans un environnement � haute concurrence
utilisent
+ g�n�ralement des donn�es versionn�es pour assurer l'isolation pour les
"longues"
+ unit�s de travail.
+ </para>
+
+ <para>
+ Hibernate supporte ce mod�le en permettant pour le r�attachement
d'instances d�tach�es
+ l'utilisation des m�thodes
<literal>Session.update()</literal> ou
<literal>Session.merge()</literal> :
+ </para>
+
+ <programlisting><![CDATA[// dans la premi�re session
+Cat cat = (Cat) firstSession.load(Cat.class, catId);
+Cat potentialMate = new Cat();
+firstSession.save(potentialMate);
+
+// dans une couche plus haute de l'application
+cat.setMate(potentialMate);
+
+// plus tard, dans une nouvelle session
+secondSession.update(cat); // update cat
+secondSession.update(mate); // update mate]]></programlisting>
+
+ <para>
+ Si le <literal>Cat</literal> avec l'identifiant
<literal>catId</literal> avait d�j�
+ �t� charg� par <literal>secondSession</literal> lorsque
l'application a essay� de le
+ r�attacher, une exception aurait �t� lev�e.
+ </para>
+
+ <para>
+ Utilisez <literal>update()</literal> si vous �tes sure que la
session ne contient pas
+ d�j� une instance persistante avec le m�me identifiant, et
<literal>merge()</literal>
+ si vous voulez fusionner vos modifications n'importe quand sans
consid�rer l'�tat de
+ la session. En d'autres mots, <literal>update()</literal> est
g�n�ralement la premi�re m�thode
+ que vous devriez appeler dans une session fra�che, pour s'assurer que le
r�attachement
+ de vos instances d�tach�es est la premi�re op�ration qui est ex�cut�e.
+ </para>
+
+ <para>
+ L'application devrait individuellement
<literal>update()</literal> (NdT : mettre � jour)
+ les instances d�tach�es accessibles depuis l'instance d�tach�e donn�e si
et
+ <emphasis>seulement</emphasis> si elle veut que leur �tat soit
aussi mis � jour. Ceci
+ peut �tre automatis� bien s�r, en utilisant la <emphasis>persistance
transitive</emphasis>,
+ voir <xref linkend="objectstate-transitive"/>.
+ </para>
+
+ <para>
+ La m�thode <literal>lock()</literal> permet aussi � une
application de r�associer un
+ objet avec une nouvelle session. Pourtant, l'instance d�tach�e doit �tre
non modifi�e !
+ </para>
+
+ <programlisting><![CDATA[//r�associe :
+sess.lock(fritz, LockMode.NONE);
+//fait une v�rification de version, puis r�associe :
+sess.lock(izi, LockMode.READ);
+//fait une v�rification de version, en utilisant SELECT ... FOR UPDATE, puis r�associe :
+sess.lock(pk, LockMode.UPGRADE);]]></programlisting>
+
+ <para>
+ Notez que <literal>lock()</literal> peut �tre utilis� avec
diff�rents
+ <literal>LockMode</literal>s, voir la documentation de l'API
documentation et le chapitre
+ sur la gestion des transactions pour plus d'informations. Le
r�attachement n'est pas le seul
+ cas d'utilisation pour <literal>lock()</literal>.
+ </para>
+
+ <para>
+ D'autres mod�les pour de longues unit�s de travail sont trait�s dans
<xref linkend="transactions-optimistic"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-saveorupdate">
+ <title>D�tection automatique d'un �tat</title>
+
+ <para>
+ Les utilisateurs d'Hibernate ont demand� une m�thode dont l'intention
g�n�rale
+ serait soit de sauvegarder une instance �ph�m�re en g�n�rant un nouvel
identifiant,
+ soit mettre � jour/r�attacher les instances d�tach�es associ�es �
l'identifiant courant.
+ La m�thode <literal>saveOrUpdate()</literal> impl�mente cette
fonctionnalit�.
+ </para>
+
+ <programlisting><![CDATA[// dans la premi�re session
+Cat cat = (Cat) firstSession.load(Cat.class, catID);
+
+// dans une partie plus haute de l'application
+Cat mate = new Cat();
+cat.setMate(mate);
+
+// plus tard, dans une nouvelle session
+secondSession.saveOrUpdate(cat); // met � jour un �tat existant (cat a un identifiant
non-null)
+secondSession.saveOrUpdate(mate); // sauvegarde les nouvelles instances (mate a un
identiant null)]]></programlisting>
+
+ <para>
+ L'usage et la s�mantique de <literal>saveOrUpdate()</literal>
semble �tre confuse pour les
+ nouveaux utilisateurs. Premi�rement, aussi longtemps que vous n'essayez
pas d'utiliser des
+ instances d'une session dans une autre, vous ne devriez pas avoir besoin
d'utiliser <literal>update()</literal>,
+ <literal>saveOrUpdate()</literal>, ou
<literal>merge()</literal>. Certaines applications
+ n'utiliseront jamais ces m�thodes.
+ </para>
+
+ <para>
+ G�n�ralement <literal>update()</literal> ou
<literal>saveOrUpdate()</literal> sont utilis�es dans
+ le sc�nario suivant :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ l'application charge un objet dans la premi�re session
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ l'objet est pass� � la couche utilisateur
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ certaines modifications sont effectu�es sur l'objet
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ l'objet est retourn� � la couche logique m�tier
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ l'application persiste ces modifications en appelant
+ <literal>update()</literal> dans une seconde sessin
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <literal>saveOrUpdate()</literal> s'utilise dans le cas
suivant :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ si l'objet est d�j� persistant dans cette session, ne rien faire
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ si un autre objet associ� � la session a le m�me identifiant, lever
une exception
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ si l'objet n'a pas de propri�t� d'identifiant, appeler
<literal>save()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ si l'identifiant de l'objet a une valeur assign�e � un objet
nouvellement instanci�,
+ appeler <literal>save()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ si l'objet est versionn� (par
<literal><version></literal> ou
+ <literal><timestamp></literal>), et la
valeur de la propri�t� de version
+ est la m�me valeur que celle assign�e � un objet nouvellement
instanci�, appeler
+ <literal>save()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ sinon mettre � jour l'objet avec
<literal>update()</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ et <literal>merge()</literal> est tr�s diff�rent :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ s'il y a une instance persistante avec le m�me identifiant
couramment
+ associ�e � la session, copier l'�tat de l'objet donn� dans
l'instance persistante
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ s'il n'y a pas d'instance persistante associ�e � cette
session, essayer de le charger
+ � partir de la base de donn�es, ou cr�er une nouvelle instance
persistante
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ l'instance persistante est retourn�e
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ l'instance donn�e ne devient pas associ�e � la session, elle
reste d�tach�e
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id="objectstate-deleting" revision="1">
+ <title>Suppression d'objets persistants</title>
+
+ <para>
+ <literal>Session.delete()</literal> supprimera l'�tat
d'un objet de la base de donn�es.
+ Bien s�r, votre application pourrait encore conserver une r�f�rence vers un
objet effac�.
+ Il est mieux de penser � <literal>delete()</literal> comme
rendant une instance persistante
+ �ph�m�re.
+ </para>
+
+ <programlisting><![CDATA[sess.delete(cat);]]></programlisting>
+
+ <para>
+ Vous pouvez effacer des objets dans l'ordre que vous voulez, sans risque
de violations
+ de contrainte de clef �trang�re. Il est encore possible de violer une
contrainte <literal>NOT
+ NULL</literal> sur une colonne de clef �trang�re en effa�ant des objets
dans le
+ mauvais ordre, par exemple si vous effacer le parent, mais oubliez
d'effacer les enfants.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-replicating" revision="1">
+ <title>R�plication d'objets entre deux entrep�ts de
donn�es</title>
+
+ <para>
+ Il est occasionnellement utile de pouvoir prendre un graphe d'instances
persistantes
+ et de les rendre persistantes dans un entrep�t diff�rent, sans reg�n�rer les
valeurs
+ des identifiants.
+ </para>
+
+ <programlisting><![CDATA[//r�cup�re un cat de la base de donn�es
+Session session1 = factory1.openSession();
+Transaction tx1 = session1.beginTransaction();
+Cat cat = session1.get(Cat.class, catId);
+tx1.commit();
+session1.close();
+
+// r�concilie la seconde base de donn�es
+Session session2 = factory2.openSession();
+Transaction tx2 = session2.beginTransaction();
+session2.replicate(cat, ReplicationMode.LATEST_VERSION);
+tx2.commit();
+session2.close();]]></programlisting>
+
+ <para>
+ Le <literal>ReplicationMode</literal> d�termine comment
<literal>replicate()</literal>
+ traitera les conflits avec les lignes existantes dans la base de donn�es.
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ReplicationMode.IGNORE</literal> - ignore
l'objet s'il y a une ligne
+ existante dans la base de donn�es avec le m�me identifiant
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.OVERWRITE</literal> - �crase
n'importe quelle ligne existante
+ dans la base de donn�es avec le m�me identifiant
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.EXCEPTION</literal> - l�ve une
exception s'il y une ligne dans
+ la base de donn�es avec le m�me identifiant
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ReplicationMode.LATEST_VERSION</literal> -
�crase la ligne si son num�ro de version
+ est plus petit que le num�ro de version de l'objet, ou ignore
l'objet sinon
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Les cas d'utilisation de cette fonctionnalit� incluent la r�conciliation
de donn�es
+ entr�es dans diff�rentes base de donn�es, l'extension des informations de
configuration
+ du syst�me durant une mise � jour du produit, retour en arri�re sur les
changements effectu�s
+ durant des transactions non-ACID, et plus.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-flushing">
+ <title>Flush de la session</title>
+
+ <para>
+ De temps en temps la <literal>Session</literal> ex�cutera les
expressions SQL
+ requises pour syncrhoniser l'�tat de la connexion JDBC avec l'�tat
des objets
+ retenus en m�moire. Ce processus, <emphasis>flush</emphasis>,
arrive par d�faut aux
+ points suivants :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ lors de certaines ex�cutions de requ�te
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ lors d'un appel �
<literal>org.hibernate.Transaction.commit()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ lors d'un appel � <literal>Session.flush()</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Les expressions SQL sont effectu�es dans l'ordre suivant :
+ </para>
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ insertion des entit�s, dans le m�me ordre que celui des
+ objets correspondants sauvegard�s par l'appel �
<literal>Session.save()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ mise � jours des entit�s
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ suppression des collections
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ suppression, mise � jour et insertion des �l�ments des collections
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ insertion des collections
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ suppression des entit�s, dans le m�me ordre que celui des objets
+ correspondants qui ont �t� supprim�s par l'appel �
<literal>Session.delete()</literal>
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ (Une exception est que des objets utilisant la g�n�ration
<literal>native</literal>
+ d'identifiants sont ins�r�s lorsqu'ils sont sauvegard�s.)
+ </para>
+
+ <para>
+ Except� lorsque vous appelez <literal>flush()</literal>
explicitement, il n'y
+ absolument aucune garantie � propos de <emphasis>quand</emphasis>
la <literal>Session</literal>
+ ex�cute les appels JDBC, seulement sur
l'<emphasis>ordre</emphasis> dans lequel ils sont
+ ex�cut�s. Cependant, Hibernate garantit que
<literal>Query.list(..)</literal> ne
+ retournera jamais de donn�es p�rim�es, ni des donn�es fausses.
+ </para>
+
+ <para>
+ Il est possible de changer le comportement par d�faut, donc que le flush se
produise
+ moins fr�quemment. La classe <literal>FlushMode</literal> d�finit
trois modes diff�rents :
+ flush seulement lors du commit (et seulement quand l'API
<literal>Transaction</literal>
+ d'Hibernate est utilis�e), flush automatiquement en utilisant la
proc�dure expliqu�e, ou
+ jamais de flush � moins que <literal>flush()</literal> soit
appel�e explicitement.
+ Le dernier mode est utile pour l'ex�cution de longues unit�s de travail,
o� une
+ <literal>Session</literal> est gard�e ouverte et d�connect�e pour
un long moment
+ (voir <xref
linkend="transactions-optimistic-longsession"/>).
+ </para>
+
+ <programlisting><![CDATA[sess = sf.openSession();
+Transaction tx = sess.beginTransaction();
+sess.setFlushMode(FlushMode.COMMIT); // permet aux requ�tes de retourner un �tat p�rim�
+
+Cat izi = (Cat) sess.load(Cat.class, id);
+izi.setName(iznizi);
+
+// pourrait retourner des donn�es p�rim�es
+sess.find("from Cat as cat left outer join cat.kittens kitten");
+
+// le changement pour izi n'est pas flush� !
+...
+tx.commit(); // le flush se produit]]></programlisting>
+
+ <para>
+ Durant le flush, une exception peut se produire (par exemple, si une
op�ration de la
+ DML viole une contrainte). Puisque les exceptions de gestion impliquent une
certaine
+ compr�hension du comportement transactionnel d'Hibernate, nous le
traitons dans
+ <xref linkend="transactions"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-transitive" revision="1">
+ <title>Persistance transitive</title>
+
+ <para>
+ Il est assez p�nible de sauvegarder, supprimer, ou r�attacher des objets
+ un par un, surtout si vous traitez un graphe d'objets associ�s. Un cas
habituel
+ est une relation parent/enfant. Consid�rez l'exemple suivant :
+ </para>
+
+ <para>
+ Si les enfants de la relation parent/enfant �taient des types de valeur (par
exemple,
+ une collection d'adresses ou de cha�nes de caract�res), leur cycle de vie
d�pendraient
+ du parent et aucune action ne serait requise pour "cascader"
facilement les
+ changements d'�tat. Si le parent est sauvegard�, les objets enfants de
type de valeur sont
+ sauvegard�s �galement, si le parent est supprim�, les enfants sont supprim�s,
etc. Ceci
+ fonctionne m�me pour des op�rations telles que la suppression d'un enfant
de la collection ;
+ Hibernate d�tectera cela et, puisque les objets de type de valeur ne peuvent
pas avoir
+ des r�f�rences partag�es, supprimera l'enfant de la base de donn�es.
+ </para>
+
+ <para>
+ Maintenant consid�rez le m�me sc�nario avec un parent et dont les objets
enfants
+ sont des entit�s, et non des types de valeur (par exemple, des cat�gories et
des
+ objets, ou un parent et des chatons). Les entit�s ont leur propre cycle de
vie,
+ supportent les r�f�rences partag�es (donc supprimer une entit� de la
collection
+ ne signifie pas qu'elle peut �tre supprim�e), et il n'y a par d�faut
pas de
+ cascade d'�tat d'une entit� vers n'importe quelle entit�
associ�e. Hibernate
+ n'impl�mente pas la <emphasis>persistance par
accessibilit�</emphasis> par d�faut.
+ </para>
+
+ <para>
+ Pour chaque op�ration basique de la session d'Hibernate - incluant
<literal>persist(), merge(),
+ saveOrUpdate(), delete(), lock(), refresh(), evict(),
replicate()</literal> - il y a un
+ style de cascade correspondant. Respectivement, les styles de cascade
s'appellent <literal>persist,
+ merge, save-update, delete, lock, refresh, evict, replicate</literal>.
Si vous voulez qu'une
+ op�ration soit cascad�e le long d'une association, vous devez
l'indiquer dans le document de
+ mapping. Par exemple :
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person"
cascade="persist"/>]]></programlisting>
+
+ <para>
+ Les styles de cascade peuvent �tre combin�s :
+ </para>
+
+ <programlisting><![CDATA[<one-to-one name="person"
cascade="persist,delete,lock"/>]]></programlisting>
+
+ <para>
+ Vous pouvez m�me utiliser
<literal>cascade="all"</literal> pour sp�cifier que
<emphasis>toutes</emphasis>
+ les op�rations devraient �tre cascad�es le long de l'association. La
valeur par d�faut
+ <literal>cascade="none"</literal> sp�cifie
qu'aucune op�ration ne sera cascad�e.
+ </para>
+
+ <para>
+ Une style de cascade sp�cial, <literal>delete-orphan</literal>,
s'applique seulement
+ aux associations un-vers-plusieurs, et indique que l'op�ration
<literal>delete()</literal>
+ devrait �tre appliqu�e � n'importe quel enfant qui est supprim� de
l'association.
+ </para>
+
+
+ <para>
+ Recommandations :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Cela n'a g�n�ralement aucun sens d'activer la cascade sur une
association
+ <literal><many-to-one></literal> ou
<literal><many-to-many></literal>. Les
+ cascades sont souvent utiles pour des associations
+ <literal><one-to-one></literal> et
<literal><one-to-many></literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Si la dur�e de vie de l'objet enfant est li�e � la dur�e de vie
de l'objet parent,
+ faites en un <emphasis>objet du cycle de vie</emphasis>
en sp�cifiant
+
<literal>cascade="all,delete-orphan"</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Sinon, vous pourriez ne pas avoir besoin de cascade du tout. Mais si
vous pensez que vous
+ travaillerez souvent avec le parent et les enfants ensemble dans la
m�me transaction, et
+ que vous voulez vous �viter quelques frappes, consid�rez
l'utilisation de
+
<literal>cascade="persist,merge,save-update"</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Mapper une association (soit une simple association valu�e, soit une
collection) avec
+ <literal>cascade="all"</literal> marque
l'association comme une relation de style
+ <emphasis>parent/enfant</emphasis> o� la sauvegarde/mise �
jour/suppression du parent
+ entra�ne la sauvegarde/mise � jour/suppression de l'enfant ou des
enfants.
+ </para>
+ <para>
+ En outre, une simple r�f�rence � un enfant d'un parent persistant aura
pour cons�quence
+ la sauvegarde/mise � jour de l'enfant. Cette m�taphore est cependant
incompl�te. Un enfant
+ qui devient non r�f�renc� par son parent <emphasis>n'est
pas</emphasis> automatiquement
+ supprim�e, except� dans le cas d'une association
<literal><one-to-many></literal>
+ mapp�e avec <literal>cascade="delete-orphan"</literal>.
La s�mantique pr�cise des op�rations
+ de cascade pour une relation parent/enfant est la suivante :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Si un parent est pass� � <literal>persist()</literal>,
tous les enfant sont pass�s �
+ <literal>persist()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Si un parent est pass� � <literal>merge()</literal>, tous
les enfants sont pass�s �
+ <literal>merge()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Si un parent est pass� � <literal>save()</literal>,
<literal>update()</literal> ou
+ <literal>saveOrUpdate()</literal>, tous les enfants sont
pass�s � <literal>saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Si un enfant d�tach� ou �ph�m�re devient r�f�renc� par un parent
persistant,
+ il est pass� � <literal>saveOrUpdate()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Si un parent est supprim�, tous les enfants sont pass�s �
<literal>delete()</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Si un enfant est d�r�f�renc� par un parent persistant,
<emphasis>rien de sp�cial
+ n'arrive</emphasis> - l'application devrait
explicitement supprimer l'enfant si n�cessaire -
+ � moins que
<literal>cascade="delete-orphan"</literal> soit param�tr�,
+ au quel cas l'enfant "orphelin" est supprim�.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Enfin, la cascade des op�rations peut �tre effectu�e sur un graphe donn�
lors
+ de l'<emphasis>appel de l'op�ration</emphasis> or lors du
<emphasis>flush</emphasis>
+ suivant. Toutes les op�rations, lorsque cascad�es, le sont sur toutes les entit�s
+ associ�es atteignables lorsque l'op�tation est ex�cut�e. Cependant
+ <literal>save-upate</literal> et
<literal>delete-orphan</literal> sont cascad�es
+ � toutes les entit�s associ�es atteignables lors du flush de la
+ <literal>Session</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="objectstate-metadata">
+ <title>Utilisation des m�ta-donn�es</title>
+
+ <para>
+ Hibernate requiert un mod�le de m�ta-niveau tr�s riche de toutes les entit�s
et types valu�s.
+ De temps en temps, ce mod�le est tr�s utile � l'application elle m�me.
Par exemple,
+ l'application pourrait utiliser les m�ta-donn�es d'Hibernate pour
impl�menter un algorithme
+ de copie en profondeur "intelligent" qui comprendrait quels objets
devraient copi�s
+ (par exemple les types de valeur mutables) et lesquels ne devraient pas
l'�tre (par exemple
+ les types de valeurs immutables et, possiblement, les entit�s associ�es).
+ </para>
+ <para>
+ Hibernate expose les m�ta-donn�es via les interfaces
<literal>ClassMetadata</literal>
+ et <literal>CollectionMetadata</literal> et la hi�rarchie
<literal>Type</literal>.
+ Les instances des interfaces de m�ta-donn�es peuvent �tre obtenues � partir
de la
+ <literal>SessionFactory</literal>.
+ </para>
+
+ <programlisting><![CDATA[Cat fritz = ......;
+ClassMetadata catMeta = sessionfactory.getClassMetadata(Cat.class);
+
+Object[] propertyValues = catMeta.getPropertyValues(fritz);
+String[] propertyNames = catMeta.getPropertyNames();
+Type[] propertyTypes = catMeta.getPropertyTypes();
+
+// r�cup�re une Map de toutes les propri�t�s qui ne sont pas des collections ou des
associations
+Map namedValues = new HashMap();
+for ( int i=0; i<propertyNames.length; i++ ) {
+ if ( !propertyTypes[i].isEntityType() && !propertyTypes[i].isCollectionType()
) {
+ namedValues.put( propertyNames[i], propertyValues[i] );
+ }
+}]]></programlisting>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/toolset_guide.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/toolset_guide.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/toolset_guide.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/toolset_guide.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,594 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="toolsetguide" revision="2">
+ <title>Guide des outils</title>
+
+ <para>
+ Des outils en ligne de commande, des plugins Eclipse ainsu que des t�ches Ant
permettent de g�rer de cycles de d�veloppement complet
+ de projets utilisant Hibernate.
+ </para>
+
+ <para>
+ Les <emphasis>outils Hibernate</emphasis> actuels incluent des
plugins pour l'IDE Eclipse ainsi que des t�ches Ant pour l'ing�nierie
+ inverse de bases de donn�es existantes :
+ </para>
+
+ <itemizedlist>
+ <listitem><para>
+ <emphasis>Mapping Editor :</emphasis> un �diteur pour les
fichiers de mapping XML Hibernate, supportant l'auto-compl�tion et la mise en valeur
de la syntaxe.
+ Il supporte aussi l'auto-compl�tion automatique pour les noms de classes
et les noms de propri�t�/champ,
+ le rendant beaucoup plus polyvalent qu'un �diteurXML normal.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Console :</emphasis> la console est une nouvelle vue
d'Eclipse. En plus de la vue d'ensemble
+ arborescente de vos configurations de console, vous obtenez aussi une vue
interactive de vos classes persistantes et de leurs relations.
+ La console vous permet d'ex�cuter des requ�te HQL dans votre base de
donn�es et de parcourir les r�sultats directement dans Eclipse.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>Development Wizards :</emphasis> plusieurs assistants
sont fournis avec les outils d'Hibernate
+ pour Eclipse ; vous pouvez utiliser un assistant pour g�n�rer rapidement les
fichiers de configuration d'Hibernate (cfg.xml),
+ ou vous pouvez m�me compl�tement g�n�rer les fichiers de mapping Hibernate et
les sources des POJOs � partir d'un sch�ma de base de donn�es existant.
+ L'assistant d'ing�nierie inverse supporte les mod�les utilisateur.
+ </para></listitem>
+ <listitem><para>
+ <emphasis>T�ches Ant :</emphasis>
+ </para></listitem>
+
+ </itemizedlist>
+
+ <para>
+ Veuillez-vous r�f�rer au paquet <emphasis>outils Hibernate</emphasis>
et sa documentation pour plus d'informations.
+ </para>
+
+ <para>
+ Pourtant, le paquet principal d'Hibernate arrive avec un lot d'outils
int�gr�s (il peut m�me �tre utilis� de "l'int�rieur" d'Hibernate � la
vol�e) :
+ <emphasis>SchemaExport</emphasis> aussi connu comme
+ <literal>hbm2ddl</literal>.
+ </para>
+
+ <sect1 id="toolsetguide-s1" revision="2">
+ <title>G�n�ration automatique du sch�ma</title>
+
+ <para>
+ La DDL peut �tre g�n�r�e � partir de vos fichiers de mapping par un
utilitaire d'Hibernate. Le sch�ma g�n�r�
+ inclut les contraintes d'int�grit� r�f�rentielle (clefs primaires et
�trang�res) pour les tables d'entit�s
+ et de collections. Les tables et les s�quences sont aussi cr��es pour les
g�n�rateurs d'identifiant mapp�s.
+ </para>
+
+ <para>
+ Vous <emphasis>devez</emphasis> sp�cifier un
<literal>Dialect</literal> SQL via la propri�t�
+ <literal>hibernate.dialect</literal> lors de l'utilisation de
cet outils, puisque la DDL est
+ fortement d�pendante de la base de donn�es.
+ </para>
+
+ <para>
+ D'abord, personnalisez vos fichiers de mapping pour am�liorer le sch�ma
g�n�r�.
+ </para>
+
+ <sect2 id="toolsetguide-s1-2" revision="3">
+ <title>Personnaliser le sch�ma</title>
+
+ <para>
+ Plusieurs �l�ments du mapping hibernate d�finissent des attributs
optionnels
+ nomm�s <literal>length</literal>,
<literal>precision</literal> et <literal>scale</literal>.
+ Vous pouvez param�trer la longueur, la pr�cision,... d'une colonne
avec ces attributs.
+ </para>
+
+ <programlisting><![CDATA[<property name="zip"
length="5"/>]]></programlisting>
+ <programlisting><![CDATA[<property name="balance"
precision="12" scale="2"/>]]></programlisting>
+
+ <para>
+ Certains �l�ments acceptent aussi un attribut
<literal>not-null</literal>
+ (utilis� pour g�n�rer les contraintes de colonnes <literal>NOT
NULL</literal>) et
+ un attribut <literal>unique</literal> (pour g�n�rer une
contrainte de colonne
+ <literal>UNIQUE</literal>).
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar"
column="barId" not-null="true"/>]]></programlisting>
+ <programlisting><![CDATA[<element column="serialNumber"
type="long" not-null="true"
unique="true"/>]]></programlisting>
+
+ <para>
+ Un attribut <literal>unique-key</literal> peut �tre utilis�
pour grouper les colonnes
+ en une seule contrainte d'unicit�. Actuellement, la valeur sp�cifi�e
par
+ l'attribut <literal>unique-key</literal> n'est
<emphasis>pas</emphasis> utilis�e pour
+ nommer la contrainte dans le DDL g�n�r�, elle sert juste � grouper les
colonnes
+ dans le fichier de mapping.
+ </para>
+ <programlisting><![CDATA[<many-to-one name="org"
column="orgId" unique-key="OrgEmployeeId"/>
+ <property name="employeeId"
unique-key="OrgEmployeeId"/>]]></programlisting>
+
+ <para>
+ Un attribut <literal>index</literal> indique le nom d'un
index qui sera
+ cr�� en utilisant la ou les colonnes mapp�es. Plusieurs colonnes
+ peuvent �tre group�es dans un m�me index, en sp�cifiant le m�me
+ nom d'index.
+ </para>
+
+ <programlisting><![CDATA[<property name="lastName"
index="CustName"/>
+<property name="firstName"
index="CustName"/>]]></programlisting>
+
+ <para>
+ Un attribut <literal>foreign-key</literal> peut �tre utilis�
pour surcharger le nom
+ des cl�s �trang�res g�n�r�es.
+ </para>
+
+ <programlisting><![CDATA[<many-to-one name="bar"
column="barId"
foreign-key="FKFooBar"/>]]></programlisting>
+
+ <para>
+ Plusieurs �l�ments de mapping acceptent aussi un �l�ment fils
<literal><column></literal>.
+ Ceci est utile pour les type multi-colonnes:
+ </para>
+
+ <programlisting><![CDATA[<property name="name"
type="my.customtypes.Name"/>
+ <column name="last" not-null="true" index="bar_idx"
length="30"/>
+ <column name="first" not-null="true" index="bar_idx"
length="20"/>
+ <column name="initial"/>
+</property>]]></programlisting>
+
+ <para>
+ L'attribut <literal>default</literal> vous laisse
sp�cifier une valeur par d�faut pour
+ une colonnes (vous devriez assigner la m�me valeur � la propri�t� mapp�e
avant de sauvegarder une nouvelle instance
+ de la classe mapp�e).
+ </para>
+
+ <programlisting><![CDATA[<property name="credits"
type="integer" insert="false">
+ <column name="credits" default="10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<version name="version"
type="integer" insert="false">
+ <column name="version" default="0"/>
+</property>]]></programlisting>
+
+ <para>
+ L'attribut <literal>sql-type</literal> laisse
l'utilisateur surcharger le mapping
+ par d�faut du type Hibernate vers un type SQL.
+ </para>
+
+ <programlisting><![CDATA[<property name="balance"
type="float">
+ <column name="balance" sql-type="decimal(13,3)"/>
+</property>]]></programlisting>
+
+
+ <para>
+ L'attribut <literal>check</literal> permet de sp�cifier
une contrainte de v�rification.
+ </para>
+
+ <programlisting><![CDATA[<property name="foo"
type="integer">
+ <column name="foo" check="foo > 10"/>
+</property>]]></programlisting>
+
+ <programlisting><![CDATA[<class name="Foo"
table="foos" check="bar < 100.0">
+ ...
+ <property name="bar" type="float"/>
+</class>]]></programlisting>
+
+
+ <table frame="topbot" id="schemattributes-summary"
revision="2">
+ <title>Summary</title>
+ <tgroup cols="3">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2.5*"/>
+ <thead>
+ <row>
+ <entry>Attribut</entry>
+ <entry>Valeur</entry>
+ <entry>Interpr�tation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+
<entry><literal>length</literal></entry>
+ <entry>num�rique</entry>
+ <entry>taille d'une colonne</entry>
+ </row>
+ <row>
+
<entry><literal>precision</literal></entry>
+ <entry>num�rique</entry>
+ <entry>pr�cision d�cimale de la colonne</entry>
+ </row>
+ <row>
+
<entry><literal>scale</literal></entry>
+ <entry>num�rique</entry>
+ <entry>scale d�cimale de la colonne</entry>
+ </row>
+ <row>
+
<entry><literal>not-null</literal></entry>
+
<entry><literal>true|false</literal></entry>
+ <entry>sp�cifie que la colonne doit �tre
non-nulle</entry>
+ </row>
+ <row>
+
<entry><literal>unique</literal></entry>
+
<entry><literal>true|false</literal></entry>
+ <entry>sp�cifie que la colonne doit avoir une
contrainte d'unicit�</entry>
+ </row>
+ <row>
+
<entry><literal>index</literal></entry>
+
<entry><literal>index_name</literal></entry>
+ <entry>sp�cifie le nom d'un index
(multi-colonnes)</entry>
+ </row>
+ <row>
+
<entry><literal>unique-key</literal></entry>
+
<entry><literal>unique_key_name</literal></entry>
+ <entry>sp�cifie le nom d'une contrainte
d'unicit� multi-colonnes</entry>
+ </row>
+ <row>
+
<entry><literal>foreign-key</literal></entry>
+
<entry><literal>foreign_key_name</literal></entry>
+ <entry>
+ sp�cifie le nom d'une contrainte de cl� �trang�re
g�n�r�e pour
+ une association, utilisez-la avec les �l�ments de
mapping
+ <one-to-one>, <many-to-one>,
<key>, et <many-to-many>
+ Notez que les extr�mit�s
<literal>inverse="true"</literal>
+ se seront pas prises en compte par
<literal>SchemaExport</literal>.
+ </entry>
+ </row>
+ <row>
+
<entry><literal>sql-type</literal></entry>
+ <entry><literal>SQL
column_type</literal></entry>
+ <entry>
+ surcharge le type par d�faut (attribut de
+ l'�l�ment
<literal><column></literal> uniquement)
+ </entry>
+ </row>
+ <row>
+
<entry><literal>default</literal></entry>
+ <entry>expression SQL</entry>
+ <entry>
+ sp�cifie une valeur par d�faut pour la colonne
+ </entry>
+ </row>
+ <row>
+
<entry><literal>check</literal></entry>
+ <entry>SQL expression</entry>
+ <entry>
+ cr�e une contrainte de v�rification sur la table ou la
colonne
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ L'�l�ment <literal><comment></literal> vous
permet de sp�cifier un commentaire pour le sch�ma g�n�r�.
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer"
table="CurCust">
+ <comment>Current customers only</comment>
+ ...
+</class>]]></programlisting>
+
+ <programlisting><![CDATA[<property name="balance">
+ <column name="bal">
+ <comment>Balance in USD</comment>
+ </column>
+</property>]]></programlisting>
+
+ <para>
+ Ceci a pour r�sultat une expression
+ <literal>comment on table</literal> ou
+ <literal>comment on column</literal> dans la DDL g�n�r�e (o�
support�e).
+ </para>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-3" revision="2">
+ <title>Ex�cuter l'outil</title>
+
+ <para>
+ L'outil <literal>SchemaExport</literal> g�n�re un script
DDL vers
+ la sortie standard et/ou ex�cute les ordres DDL.
+ </para>
+
+ <para>
+ <literal>java -cp
</literal><emphasis>classpath_hibernate</emphasis>
+ <literal>net.sf.hibernate.tool.hbm2ddl.SchemaExport</literal>
<emphasis>options fichiers_de_mapping</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaExport</literal> Options de la
ligne de commande</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+
<entry><literal>--quiet</literal></entry>
+ <entry>ne pas �crire le script vers la sortie
standard</entry>
+ </row>
+ <row>
+
<entry><literal>--drop</literal></entry>
+ <entry>supprime seuleument les tables</entry>
+ </row>
+ <row>
+
<entry><literal>--create</literal></entry>
+ <entry>ne cr�� que les tables</entry>
+ </row>
+ <row>
+
<entry><literal>--text</literal></entry>
+ <entry>ne pas ex�cuter sur la base de
donn�es</entry>
+ </row>
+ <row>
+
<entry><literal>--output=my_schema.ddl</literal></entry>
+ <entry>�crit le script ddl vers un
fichier</entry>
+ </row>
+ <row>
+
<entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>s�lectionne une
<literal>NamingStrategy</literal></entry>
+ </row>
+ <row>
+
<entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>lit la configuration Hibernate � partir d'un
fichier XML</entry>
+ </row>
+ <row>
+
<entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>lit les propri�t�s de la base de donn�es �
partir d'un fichier</entry>
+ </row>
+ <row>
+
<entry><literal>--format</literal></entry>
+ <entry>formatte proprement le SQL g�n�r� dans le
script</entry>
+ </row>
+ <row>
+
<entry><literal>--delimiter=x</literal></entry>
+ <entry>param�tre un d�limiteur de fin de ligne pour le
script</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Vous pouvez m�me int�grer <literal>SchemaExport</literal>
dans votre application :
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaExport(cfg).create(false, true);]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-4">
+ <title>Propri�t�s</title>
+
+ <para>
+ Les propri�t�s de la base de donn�es peuvent �tre sp�cifi�es
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>comme propri�t�s syst�me avec
<literal>-D</literal><emphasis><property></emphasis></para>
+ </listitem>
+ <listitem>
+ <para>dans
<literal>hibernate.properties</literal></para>
+ </listitem>
+ <listitem>
+ <para>dans un fichier de propri�t�s d�clar� avec
<literal>--properties</literal></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Les propri�t�s n�cessaires sont :
+ </para>
+
+ <table frame="topbot">
+ <title>SchemaExport Connection Properties</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Nom de la propri�t�</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+
<entry><literal>hibernate.connection.driver_class</literal></entry>
+ <entry>classe du driver JDBC</entry>
+ </row>
+ <row>
+
<entry><literal>hibernate.connection.url</literal></entry>
+ <entry>URL JDBC</entry>
+ </row>
+ <row>
+
<entry><literal>hibernate.connection.username</literal></entry>
+ <entry>utilisateur de la base de donn�es</entry>
+ </row>
+ <row>
+
<entry><literal>hibernate.connection.password</literal></entry>
+ <entry>mot de passe de l'utilisateur</entry>
+ </row>
+ <row>
+
<entry><literal>hibernate.dialect</literal></entry>
+ <entry>dialecte</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-5">
+ <title>Utiliser Ant</title>
+
+ <para>
+ Vous pouvez appeler <literal>SchemaExport</literal> depuis
votre script
+ de construction Ant :
+ </para>
+
+ <programlisting><![CDATA[<target
name="schemaexport">
+ <taskdef name="schemaexport"
+ classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
+ classpathref="class.path"/>
+
+ <schemaexport
+ properties="hibernate.properties"
+ quiet="no"
+ text="no"
+ drop="no"
+ delimiter=";"
+ output="schema-export.sql">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaexport>
+</target>]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-6" revision="2">
+ <title>Mises � jour incr�mentales du sch�ma</title>
+
+ <para>
+ L'outil <literal>SchemaUpdate</literal> mettra � jour un
sch�ma existant
+ en effectuant les changement par "incr�ment".
+ Notez que <literal>SchemaUpdate</literal> d�pends beaucoup de
l'API JDBC
+ metadata, il ne fonctionnera donc pas avec tous les drivers JDBC.
+ </para>
+
+ <para>
+ <literal>java -cp
</literal><emphasis>classpath_hibernate</emphasis>
+ <literal>net.sf.hibernate.tool.hbm2ddl.SchemaUpdate</literal>
<emphasis>options fichiers_de_mapping</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaUpdate</literal> Options de ligne
de commande</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+
<entry><literal>--quiet</literal></entry>
+ <entry>ne pas �crire vers la sortie
standard</entry>
+ </row>
+ <row>
+
<entry><literal>--text</literal></entry>
+ <entry>ne pas exporter vers la base de
donn�es</entry>
+ </row>
+ <row>
+
<entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>choisit une
<literal>NamingStrategy</literal></entry>
+ </row>
+ <row>
+
<entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>lire les propri�t�s de la base de donn�es �
partir d'un fichier</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Vous pouvez int�grer <literal>SchemaUpdate</literal> dans
votre application :
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaUpdate(cfg).execute(false);]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="toolsetguide-s1-7">
+ <title>Utiliser Ant pour des mises � jour de sch�ma par
incr�ment</title>
+
+ <para>
+ Vous pouvez appeler <literal>SchemaUpdate</literal> depuis le
script Ant :
+ </para>
+
+ <programlisting><![CDATA[<target
name="schemaupdate">
+ <taskdef name="schemaupdate"
+ classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
+ classpathref="class.path"/>
+
+ <schemaupdate
+ properties="hibernate.properties"
+ quiet="no">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemaupdate>
+</target>]]></programlisting>
+
+ <sect2 id="toolsetguide-s1-8" revision="1">
+ <title>Validation du sch�ma</title>
+
+ <para>
+ L'outil <literal>SchemaValidator</literal> validera que
le sch�ma existant correspond � vos documents de mapping.
+ Notez que le <literal>SchemaValidator</literal> d�pends de
l'API metadata de JDBC, il ne fonctionnera
+ donc pas avec tous les drivers JDBC. Cet outil est extr�mement utile pour
tester.
+ </para>
+
+ <para>
+ <literal>java -cp
</literal><emphasis>hibernate_classpaths</emphasis>
+ <literal>org.hibernate.tool.hbm2ddl.SchemaValidator</literal>
<emphasis>options mapping_files</emphasis>
+ </para>
+
+ <table frame="topbot">
+ <title><literal>SchemaValidator</literal> Options de
ligne de commande</title>
+ <tgroup cols="2">
+ <colspec colwidth="1.5*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+
<entry><literal>--naming=eg.MyNamingStrategy</literal></entry>
+ <entry>Indique une
<literal>NamingStrategy</literal></entry>
+ </row>
+ <row>
+
<entry><literal>--properties=hibernate.properties</literal></entry>
+ <entry>lit les propri�t�s dela base de donn�es depuis
un fichier de propri�t�s</entry>
+ </row>
+ <row>
+
<entry><literal>--config=hibernate.cfg.xml</literal></entry>
+ <entry>indique un fichier
<literal>.cfg.xml</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Vous pouvez inclure <literal>SchemaValidator</literal> dans
votre application:
+ </para>
+
+ <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaValidator(cfg).validate();]]></programlisting>
+
+ </sect2>
+
+ </sect2>
+ <sect2 id="toolsetguide-s1-9">
+ <title>Utiliser Ant pour la validation du Sch�ma</title>
+
+ <para>
+ Vous pouvez appeler <literal>SchemaValidator</literal> depuis
le script Ant:
+ </para>
+
+ <programlisting><![CDATA[<target
name="schemavalidate">
+ <taskdef name="schemavalidator"
+ classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
+ classpathref="class.path"/>
+
+ <schemavalidator
+ properties="hibernate.properties">
+ <fileset dir="src">
+ <include name="**/*.hbm.xml"/>
+ </fileset>
+ </schemavalidator>
+</target>]]></programlisting>
+
+ </sect2>
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/transactions.xml
(from rev 14070,
core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/transactions.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/transactions.xml
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/content/transactions.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,1074 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="transactions" revision="2">
+ <title>Transactions et acc�s concurrents</title>
+
+ <para>
+ L'un des principaux avantages du m�canisme de contr�le des acc�s concurrents
d'Hibernate est qu'il est tr�s
+ facile � comprendre. Hibernate utilise directement les connexions JDBC ainsi que
les ressources JTA sans y
+ ajouter davantage de m�canisme de blocage. Nous vous recommandons de vous
familiariser avec les sp�cifications
+ JDBC, ANSI et d'isolement de transaction de la base de donn�es que vous
utilisez.
+ </para>
+
+ <para>
+ Hibernate ne v�rouille pas vos objets en m�moire. Votre application peut suivre
le
+ comportement d�fini par le niveau d'isolation de vos transactions de base de
donn�es.
+ Notez que gr�ce � la <literal>Session</literal>, qui est aussi un
cache de scope transaction, Hibernate
+ fournit des lectures r�p�t�es pour les r�cup�ration par identifiants et les
requ�tes
+ d'entit�s (pas celle de valeurs scalaires).
+ </para>
+
+ <para>
+ En addition au versionning pour le controle automatique de concurrence, Hibernate
fournit
+ une API (mineure) pour le verrouillage perssimiste des enregistrements, en
g�n�rant
+ une syntaxe <literal>SELECT FOR UPDATE</literal>. Le controle de
concurrence optimiste
+ et cette API seront d�taill�s plus tard dans ce chapitre.
+ </para>
+
+ <para>
+ Nous aborderons la gestion des acc�s concurrents en discutant de la granularit�
des objets <literal>Configuration</literal>,
+ <literal>SessionFactory</literal>, et
<literal>Session</literal>, ainsi que de certains concepts relatifs � la base
de donn�es
+ et aux longues transactions applicatives.
+ </para>
+
+ <sect1 id="transactions-basics" revision="1">
+ <title>Gestion de session et d�limitation de transactions</title>
+
+ <para>Il est important de savoir qu'un objet
<literal>SessionFactory</literal> est un objet complexe et optimis� pour
+ fonctionner avec les threads(thread- safe). Il est co�teux � cr�er et est
ainsi pr�vu pour n'�tre instanci� qu?une
+ seule fois via un objet <literal>Configuration</literal> au
d�marrage de l'application,
+ et �tre partag� par tous les threads d'une application.
+ </para>
+
+ <para>Un objet <literal>Session</literal> est relativement
simple et n'est threadsafe. Il est �galement peu
+ co�teux � cr�er. Il devrait n'�tre utilis� qu'une seule fois, pour un
processus d'affaire ou une unit� de
+ travail ou une conversation et ensuite �tre rel�ch�. Un objet
<literal>Session</literal> ne tentera pas
+ d'obtenir de connexion ( <literal>Connection</literal> )
+ JDBC (ou de <literal>Datasource</literal> ) si ce n'est pas
n�cessaire.
+ </para>
+
+ <para>Afin de compl�ter ce tableau, vous devez �galement penser aux
transactions de base de donn�es. Une
+ transaction de base de donn�es se doit d'�tre la plus courte possible
afin de r�duire les risques de
+ collision sur des enregistrements verrouill�s. De longues transactions � la
base de donn�es nuiront �
+ l'extensibilit� de vos applications lorsque confront�es � de hauts
niveaux de charge. Par cons�quent,
+ il n'est jamais bon de maintenir une transaction ouverte pendant la dur�e
de reflexion de l'utilisateur,
+ jusqu'a ce que l'unit� de travail soit achev�e.
+ </para>
+
+ <para>Maintenant, comment d�limiter une unit� de travail? Est-ce qu'une
instance de <literal>Session</literal> peut avoir une dur�e
+ de vie d�passant plusieurs transactions � la base de donn�es, ou bien est-ce
que celles-ci doivent �tre li�es une � une?
+ Quand faut-il ouvrir et fermer une <literal>Session</literal> ?
Comment d�finir la d�marcation de vos transactions � la base de donn�es?
+ </para>
+
+ <sect2 id="transactions-basics-uow" revision="1">
+ <title>Unit� de travail</title>
+
+ <para>
+ Il est important de mentionner que d'utiliser un paradigme
<emphasis>session-par-operation</emphasis>
+ est un anti-pattern. Autrement dit: n'ouvrez et ne fermez pas la
+ <literal>Session</literal> � chacun de vos acc�s simples � la
base de donn�es dans un m�me thread! Bien s�r, le m�me raisonnement
+ s'applique sur la gestion des transactions � la base de donn�es. Les
appels � la base de donn�es
+ devraient �tre faits en ordre et selon une s�quence d�finie. Ils
devraient �galement �tre regroup�s en
+ des unit�s de travail atomiques. (Notez que l?utilisation d?une connexion
auto-commit constitue le m�me
+ anti-pattern. Ce mode de fonctionnement existe pour les applications
�mettant des commandes SQL � partir
+ d?une console. Hibernate d�sengage le mode auto-commit et s'attend �
ce qu'un serveur d'applications le
+ fasse �galement.)
+ Les transactions avec la base de donn�es ne sont jamais optionnelles,
toute communication
+ avec une base de donn�es doit se d�rouler dans une transaction, peu
importe si vous lisez
+ ou �crivez des donn�es. Comme �voqu�, le comportement auto-commit pour
lire les
+ donn�es devrait �tre �vit�, puisque plusieurs petites transactions ne
seront jamais
+ aussi efficaces qu'une seule plus grosse clairement d�finie comme
unit� de travail.
+ Ce dernier choix et en plus beaucoup plus facile a maintenir et � faire
�voluer.
+ </para>
+
+ <para>
+ Le pattern d'utilisation le plus fr�quemment rencontr� dans des
applications clients serveur
+ multi-usagers est le
<emphasis>session-per-request</emphasis>
+ (litt�ralement : Session par requ�te). Dans ce mod�le, la requ�te
d'un client est envoy�e � un serveur
+ (O� la couche de persistance est impl�ment�e via Hibernate), une
nouvelle
+ <literal>Session</literal> est ouverte et toutes les
op�rations d'acc�s � la base de donn�es sont ex�cut�es � l'int�rieur de
+ celle-ci. Lorsque le travail est termin� (et que les r�ponses � envoyer
au client ont �t� pr�par�es), la
+ session est flush�e et ferm�e. Une seule transaction � la base de donn�es
peut �tre utilis�e pour r�pondre
+ � la requ�te du client. La transaction est d�marr�e et valid�e au m�me
moment o� la Session est ouverte
+ et ferm�e. La relation entre la <literal>Session</literal> et
la <literal>Transaction</literal> est donc one-to-one.
+ Ce mod�le permet de r�pondre parfaitement aux attentes de la grande
majorit� des
+ applications.
+ </para>
+
+ <para>
+ Le d�fi r�side dans l'impl�mentation. Hibernate fournit une fonction
de gestion de
+ la "session courante" pour simplifier ce pattern. Tout ce que
vous devez faire
+ est d�marrer une transaction lorsqu'une requ�te est trait�e par le
serveur, et
+ la terminer avant que la r�ponse ne soit envoy�e au client. Vous pouvez
le faire
+ de la mani�re que vous voulez, les solutions communes sont un
<literal>ServletFilter</literal>,
+ l'interception via AOP avec une pointcut sur les m�thodes de type
"service", ou un conteneur
+ avec interception/proxy. Un conteneur EJB est un moyen standard
d'impl�menter ce genre d'acpect
+ tranverse comme la d�marcation des transactions sur les EJBs session, de
mani�re d�clarative
+ avec CMT. Si vous d�cidez d'utiliser la d�marcation programmatique
des transactions, pr�ferrez
+ l'API Hibernate <literal>Transaction</literal> d�taill�e
plus tard dans ce chapitre, afin de
+ facilit� l'utilisation et la portabilit� du code.
+ </para>
+
+ <para>
+ Votre application peut acc�der la "session courante" pour
ex�cuter une requ�te
+ en invoquant simplement
<literal>sessionFactory.getCurrentSession()</literal> n'importe o�
+ et autant de fois que souhait�. Vous obtiendrez toujours une
<literal>Session</literal>
+ dont le scope est la transaction courante avec la base de donn�es. Ceci
doit �tre configur�
+ soit dans les ressources local ou dans l'environnement JTA, voir
<xref linkend="architecture-current-session"/>.
+ </para>
+
+ <para>
+ Il est parfois utile d'�tendre le scope d'une
<literal>Session</literal> et d'une transaction
+ � la base de donn�es jusqu'� ce que "la vue soit rendue".
Ceci est particuli�rement
+ utile dans des applications � base de servlet qui utilisent une phase de
rendue s�par�e une fois
+ que la r�ponse a �t� pr�par�e. Etendre la transaction avec la base de
donn�es jusqu'� la fin du
+ rendering de la vue est ais� si vous impl�mentez votre propre
intercepteur. Cependant,
+ ce n'est pas facile si vous vous appuyez sur les EJBs avec CMT,
puisqu'une transaction sera
+ achev�e au retour de la m�thode EJB, avant le rendu de la vue. Rendez
vous sur le site
+ Hibernate et sur le forum pour des astuces et des exemples sur le
pattern
+ <emphasis>Open Session in View</emphasis> pattern..
+ </para>
+ </sect2>
+
+ <sect2 id="transactions-basics-apptx" revision="1">
+ <title>Longue conversation</title>
+
+ <para>Le paradigme
+ <emphasis>session-per-request</emphasis>
+ n'est pas le seul �l�ment � utiliser dans le design de vos unit�s de
travail. Plusieurs processus
+ d'affaire requi�rent toute une s�rie d'interactions avec
l'utilisateur, entrelac�es d'acc�s � la base de
+ donn�e. Dans une application Web ou une application d'entreprise, il
serait inacceptable que la dur�e de
+ vie d'une transaction s'�tale sur plusieurs interactions avec
l'usager. Consid�rez l'exemple suivant:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Un �cran s'affiche. Les donn�es vues par l'usager
ont �t� charg�es dans l'instance d'un objet
+ <literal>Session</literal> , dans le cadre d'une
transaction de base de donn�es. L'usager est libre de modifier ces objets.
+ </para>
+ </listitem>
+ <listitem>
+
+ <para>L'usager clique "Sauvegarder" apr�s 5
minutes et souhaite persister les modifications qu'il a
+ apport�es. Il s'attend � �tre la seule personne a avoir
modifi� ces donn�es et qu'aucune
+ modification conflictuelle ne se soit produite durant ce laps de
temps.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Ceci s'appelle une unit� de travail. Du point de vue de
l'utilisateur: une
+ <emphasis>conversation</emphasis> (ou
<emphasis>transaction d'application</emphasis>).
+ Il y a plusieurs fa�on de mettre ceci en place dans votre application.
+ </para>
+
+ <para>Une premi�re impl�mentation na�ve pourrait consister � garder la
+ <literal>Session</literal> et la transaction � la base de
donn�es ouvertes durant le temps de travail de l'usager, � maintenir les
+ enregistrements verrouill�s dans la base de donn�es afin d'�viter des
modifications concurrentes et de
+ maintenir l'isolation et l'atomicit� de la transaction de
l'usager. Ceci est un anti-pattern � �viter,
+ puisque le verrouillage des enregistrements dans la base de donn�es ne
permettrait pas � l'application
+ de g�rer un grand nombre d'usagers concurrents.
+ </para>
+
+ <para>Il appara�t donc �vident qu'il faille utiliser plusieurs
transactions BDD afin d'impl�menter la
+ conversation. Dans ce cas, maintenir l'isolation des processus
d'affaire devient
+ partiellement la responsabilit� de la couche applicative. Ainsi, la dur�e
de vie d'une conversation
+ devrait englober celle d'une ou de plusieurs transactions de base de
donn�es. Celle-ci sera
+ atomique seulement si l'�criture des donn�es mises � jour est faite
exclusivement par la derni�re
+ transaction BDD la composant. Toutes les autres sous transactions BD ne
doivent faire que la lecture de
+ donn�es. Ceci est relativement facile � mettre en place, surtout avec
l'utilisation de certaines
+ fonctionnalit�s d'Hibernate:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Versionnage Automatique</emphasis>
+ - Hibernate peut g�rer automatiquement les acc�s concurrents de
mani�re optimiste et d�tecter si
+ une modification concurrente s'est produite durant le temps
de r�flexion d'un usager.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Objets D�tach�s</emphasis>
+ - Si vous d�cidez d'utiliser le paradigme
+ <emphasis>session-par-requ�te</emphasis>
+ discut� plus haut, toutes les entit�s charg�es en m�moire
deviendront des objets d�tach�s durant
+ le temps de r�flexion de l'usager. Hibernate vous permet de
rattacher ces objets et de persister
+ les modifications y ayant �t� apport�es. Ce pattern est appel�:
+ <emphasis>session-per-
request-with-detached-objects</emphasis>
+ (litt�ralement: session- par-requ�te-avec-objets-d�tach�s). Le
versionnage automatique est
+ utilis� afin d'isoler les modifications concurrentes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>Session Longues (conversation)</emphasis>
+ - Une
+ <literal>Session</literal> Hibernate peut �tre
d�connect�e de la couche JDBC sous-jacente apr�s que commit() ait �t� appel�
+ sur une transaction � la base de donn�es et reconnect�e lors
d'une nouvelle requ�te-client. Ce
+ pattern s'appelle:
+ <emphasis>session-per-conversation</emphasis>
+ (Litt�ralement: session-par- conversation) et rend superflu le
rattachement des
+ objets. Le versionnage automatique est utilis� afin d'isoler
les modifications concurrentes.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Les deux patterns
+ <emphasis>session-per-request-with- detached-
objects</emphasis>
+ (session-par-requ�te-avec-objets- d�tach�s) et
+ <emphasis>session-per-conversation</emphasis>
+ (session-par-conversation) ont chacun leurs avantages et d�savantages qui
seront expos�s
+ dans ce m�me chapitre, dans la section au sujet du contr�le optimiste de
concurrence.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-basics-identity">
+ <title>L'identit� des objets</title>
+
+ <para>Une application peut acc�der � la m�me entit� persistante de
mani�re concurrente dans deux
+ <literal>Session</literal> s diff�rentes. Toutefois, une
instance d'une classe persistante n'est jamais partag�e par deux instances
+ distinctes de la classe
+ <literal>Session</literal> . Il existe donc deux notions de
l'identit� d'un objet:
+ </para>
+
+ <variablelist spacing="compact">
+ <varlistentry>
+ <term>Identit� BD</term>
+ <listitem>
+ <para>
+ <literal>foo.getId().equals( bar.getId()
)</literal> </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Identit� JVM</term>
+ <listitem>
+ <para>
+ <literal>foo==bar</literal> </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Ainsi, pour des objets attach�s � une
+ <literal>Session</literal>
<emphasis>pr�cise</emphasis>
+ (dans la cadre d'ex�cution (scope) d'une instance de
+ <literal>Session</literal> ), ces deux notions d'identit�
sont �quivalentes et garanties par Hibernate. Par contre, si une
+ application peut acc�der de mani�re concurrente � la m�me entit�
persistante dans deux sessions
+ diff�rentes, les deux instances seront en fait diff�rentes (en ce qui a
trait � l'identit� JVM). Les
+ conflits sont r�solus automatiquement par approche optimiste gr�ce au
syst�me de versionnage automatique
+ lorsque
+ <literal>Session.flush()</literal> ou
+ <literal>Transaction.commit()</literal> est appel�.
+ </para>
+
+ <para>Cette approche permet de rel�guer � Hibernate et � la base de
donn�es sous-jacente le soin de g�rer
+ les probl�mes d'acc�s concurrents. Cette mani�re de faire assure
�galement une meilleure extensibilit�
+ de l'application puisque assurer l'identit� JVM dans un thread ne
n�cessite pas de m�canismes de
+ verrouillage co�teux ou d'autres dispositifs de synchronisation. Une
application n'aura jamais le besoin
+ de synchroniser des objets d'affaire tant qu'elle peut garantir
qu'un seul thread aura acc�s � une
+ instance de
+ <literal>Session</literal> . Dans le cadre d'ex�cution
d'un objet
+ <literal>Session</literal> , l'application peut utiliser
en toute s�curit� <literal>==
+ </literal> pour comparer des objets.
+ </para>
+
+ <para>
+ Une application qui utiliserait <literal>==</literal> �
l'ext�rieur du cadre d'ex�cution d'une <literal>Session</literal>
+ pourrait obtenir des r�sultats inattendus et causer certains effets de bords.
Par exemple, si vous mettez 2
+ objets dans le m�me <literal>Set</literal> , ceux-ci pourraient
avoir la m�me identit� BD (i.e. ils repr�sentent le m�me enregistrement), mais leur
+ identit� JVM pourrait �tre diff�rente (elle ne peut, par d�finition, pas �tre
garantie sur deux objets
+ d�tach�s). Le d�veloppeur doit donc red�finir l'impl�mentation des
m�thodes <literal>equals()</literal> et
<literal>hashcode()</literal>
+ dans les classes persistantes et y adjoindre sa propre notion d'identit�.
Il existe toutefois une
+ restriction: Il ne faut jamais utiliser uniquement l'identifiant de la
base de donn�es dans l'impl�mentation
+ de l'�galit�; Il faut utiliser une cl� d'affaire, g�n�ralement une
combinaison de plusieurs attributs
+ uniques, si possible immuables. Les identifiants de base de donn�es vont
changer si un objet transitoire
+ (transient) devient persistant. Si une instance transitoire est contenue dans
un <literal>Set</literal> ,
+ changer le hashcode brisera le contrat du <literal>Set</literal>
. Les attributs pour les cl�s d'affaire
+ n'ont pas � �tre aussi stables que des cl�s primaires de bases de
+ donn�es. Il suffit simplement qu'elles soient stables tant et aussi
longtemps que les objets sont dans le
+ m�me <literal>Set</literal> . Veuillez consulter le site web
Hibernate pour des discussions plus pointues � ce sujet. Notez que ce
+ concept n'est pas propre � Hibernate mais bien g�n�ral �
l'impl�mentation de l'identit� et de l'�galit� en
+ Java.
+ </para>
+ </sect2>
+
+
+ <sect2 id="transactions-basics-issues">
+ <title>Probl�mes communs</title>
+
+ <para>Bien qu'il puisse y avoir quelques rares exceptions � cette
r�gle, il est recommand� de ne jamais utiliser
+ les anti-patterns
+ <emphasis>session-per- user-session</emphasis>
+ et
+ <emphasis>session-per-application</emphasis>
+ . Vous trouverez ici- bas quelques probl�mes que vous risquez de rencontrer
si vous en faite l?utilisation.
+ (Ces probl�mes pourraient quand m�me survenir avec des patterns recommand�s)
Assurez-vous de bien comprendre
+ les implications de chacun des patterns avant de prendre votre d�cision.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>L'objet
+ <literal>Session</literal> n?est pas con�u pour �tre
utilis� par de multiples threads. En cons�quence, les objets
+ potentiellement multi-thread comme les requ�tes HTTP, les EJB Session
et Swing Worker, risquent de
+ provoquer des conditions de course dans la
+ <literal>Session</literal> si celle-ci est partag�e. Dans
un environnement web classique, il serait pr�f�rable de synchroniser
+ les acc�s � la session http afin d?�viter qu?un usager ne recharge
une page assez rapidement pour
+ que deux requ�tes s?ex�cutant dans des threads concurrents
n?utilisent la m�me
+ <literal>Session</literal> .
+ </para>
+ </listitem>
+ <listitem>
+ <para>Lorsque Hibernate lance une exception, le roll back de la
transaction en cours doit �tre effectu�
+ et la
+ <literal>Session</literal> doit �tre imm�diatement
ferm�e. (Ceci sera explor� plus tard dans le chapitre.) Si la
+ <literal>Session</literal> est directement associ�e � une
application, il faut arr�ter l?application. Le roll back de la
+ transaction ne remettra pas les objets dans leur �tat du d�but de la
transaction. Ainsi, ceux-ci
+ pourraient �tre d�synchronis�s d?avec les enregistrements.
(G�n�ralement, cela ne cause pas de r�els
+ probl�mes puisque la plupart des exceptions sont non traitables et
requi�rent la reprise du
+ processus d?affaire ayant �chou�.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>La
+ <literal>Session</literal> met en m�moire cache tous les
objets persistants (les objets surveill�s et dont l'�tat est g�r� par
+ Hibernate.) Si la
+ <literal>Session</literal> est ouverte ind�finiment ou si
une trop grande quantit� d'objets y est charg�e, l?utilisation de la
+ m�moire peut potentiellement cro�tre jusqu?� atteindre le maximum
allouable � l?application
+ (java.lang.OutOfMemoryError.) Une solution � ce probl�me est
d?appeler les m�thodes
+ <literal>Session.clear()</literal> et
+ <literal>Session.evict()</literal> pour g�rer la m�moire
cache de la
+ <literal>Session</literal> . Vous pouvez �galement
utiliser des stored procedures si vous devez lancer des traitements sur de
+ grandes quantit�s d?informations. Certaines solutions sont d�crites
ici :
+ <xref linkend="batch"/>
+ . Garder une
+ <literal>Session</literal> ouverte pour toute la dur�e
d?une session usager augmente �galement consid�rablement le risque de
+ travailler avec de l?information p�rim�e.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+</sect1>
+
+<sect1 id="transactions-demarcation">
+ <title>D�marcation des transactions</title>
+
+ <para>La d�marcation des transactions est importante dans le design d?une
application. Aucune communication avec la
+ base de donn�es ne peut �tre effectu�e � l?ext�rieur du cadre d?une transaction.
(Il semble que ce concept soit
+ mal compris par plusieurs d�veloppeurs trop habitu�s � utiliser le mode
auto-commit.) M�me si certains niveaux
+ d'isolation et certaines possibilit�s offertes par les bases de donn�es
permettent de l?�viter, il n'est jamais
+ d�savantageux de toujours explicitement indiquer les bornes de transaction pour
les op�rations complexes comme
+ pour les op�rations simples de lecture.</para>
+
+ <para>Une application utilisant Hibernate peut s'ex�cuter dans un
environnement l�ger n?offrant pas la gestion
+ automatique des transactions (application autonome, application web simple ou
applications Swing) ou dans un
+ environnement J2EE offrant des services de gestion automatique des transactions
JTA. Dans un environnement
+ simple, Hibernate a g�n�ralement la responsabilit� de la gestion de son propre
pool de connexions � la base de
+ donn�es. Le d�veloppeur de l'application doit manuellement d�limiter les
transactions. En d'autres mots, il
+ appartient au d�veloppeur de g�rer les appels �
+ <literal>Transaction.begin()</literal>
+ ,
+ <literal>Transaction.commit()</literal>
+ et
+ <literal>Transaction.rollback()</literal>
+ . Un environnement transactionnel J2EE (serveur d'application J2EE) doit
offrir la gestion des transactions au
+ niveau du container J2EE. Les bornes de transaction peuvent normalement �tre
d�finies de mani�re d�clarative
+ dans les descripteurs de d�ploiement d'EJB Session, par exemple. La gestion
programmatique des transactions n'y
+ est donc pas n�cessaire. M�me les appels �
+ <literal>Session.flush()</literal>
+ sont faits automatiquement.
+ </para>
+
+ <para>Il peut �tre requis d'avoir une couche de persistance portable.
Hibernate offre donc une API appel�e
+ <literal>Transaction</literal>
+ qui sert d'enveloppe pour le syst�me de transaction natif de
l'environnement de d�ploiement. Il n'est pas
+ obligatoire d'utiliser cette API mais il est fortement conseill� de le faire,
sauf lors de l'utilisation de CMT
+ Session Bean (EJB avec transactions g�r�es automatiquement par le container
EJB).
+ </para>
+
+ <para>Il existe quatre �tapes disctinctes lors de la fermeture d'une
+ <literal>Session</literal>
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>flush de la session</para>
+ </listitem>
+ <listitem>
+ <para>commit de la transaction</para>
+ </listitem>
+ <listitem>
+ <para>Fermeture de la session (Close)</para>
+ </listitem>
+ <listitem>
+ <para>Gestion des exceptions</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>La synchronisation de bdd depuis la session (flush) a d�j� �t� expliqu�,
nous nous attarderons maintenant � la d�marcation des
+ transactions et � la gestion des exceptions dans les environnements l�gers et les
environnements J2EE.</para>
+
+
+ <sect2 id="transactions-demarcation-nonmanaged"
revision="2">
+ <title>Environnement non manag�</title>
+
+ <para>
+ Si la couche de persistance Hibernate s'ex�cute dans un environnement non
manag�, les connexions � la base de
+ donn�es seront g�n�ralement prises en charge par le m�canisme de pool
d'Hibernate. La gestion de la session
+ et de la transaction se fera donc de la mani�re suivante:</para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>
+ Vous n'avez pas � invoquer <literal>flush()</literal>
explicitement sur la <literal>Session</literal> -
+ l'appel de <literal>commit()</literal> d�clenchera
automatiquement la synchronisation (selon le <xref
linkend="objectstate-flushing">FlushMode</xref>
+ de la session. Un appel � <literal>close()</literal> marque
la fin de la session.
+ La cons�quence directe est que la connexion � la base de donn�es sera
relach�e par la session.
+ Ce code est portable est fonctionne dans les environnements non manag� ET
les environnements JTA.
+ </para>
+
+ <para>
+ Une solution plus flexible est la gestion par contexte fourni par
Hibernate que nous avons
+ d�j� rencontr�:
+ </para>
+
+ <programlisting><![CDATA[// Non-managed environment idiom with
getCurrentSession()
+try {
+ factory.getCurrentSession().beginTransaction();
+
+ // do some work
+ ...
+
+ factory.getCurrentSession().getTransaction().commit();
+}
+catch (RuntimeException e) {
+ factory.getCurrentSession().getTransaction().rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ Vous ne verrez probablement jamais ces exemples de code dans les
applications;
+ les exceptions fatales (exceptions du syst�me) ne devraient �tre trait�es
que
+ dans la couche la plus "haute". En d'autres termes, le code
qui ex�cute les appels
+ � Hibernate (� la couche de persistance) et le code qui g�re les
+ <literal>RuntimeException</literal> (qui ne peut g�n�ralement
effectuer qu'un nettoyage et une sortie)
+ sont dans des couches diff�rentes. La gestion du contexte courant par
Hibernate peut
+ simplifier notablement ce design, puisque vous devez acc�der � la gestion
des exceptions
+ de la <literal>SessionFactory</literal>, ce qui est d�crit
plus tard dans ce chapitre.
+ </para>
+
+ <para>
+ Notez que vous devriez s�lectionner
<literal>org.hibernate.transaction.JDBCTransactionFactory</literal>
+ (le d�faut), pour le second exemple
<literal>"thread"</literal> comme
+ <literal>hibernate.current_session_context_class</literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-jta" revision="2">
+ <title>Utilisation de JTA</title>
+
+ <para>Si votre couche de persistance s'ex�cute dans un serveur
d'application (par exemple, derri�re un EJB
+ Session Bean), toutes les datasource utilis�es par Hibernate feront
automatiquement partie de transactions
+ JTA globales. Hibernate propose deux strat�gies pour r�ussir cette
int�gration.</para>
+
+ <para>
+ Si vous utilisez des transactions g�r�es par un EJB (bean managed
transactions - BMT), Hibernate informera
+ le serveur d'application du d�but et de la fin des transactions si vous
utilisez l'API <literal>Transaction</literal> .
+ Ainsi, le code de gestion des transactions sera identique dans les deux types
d'environnements.
+ </para>
+
+ <programlisting><![CDATA[// BMT idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+ tx = sess.beginTransaction();
+
+ // do some work
+ ...
+
+ tx.commit();
+}
+catch (RuntimeException e) {
+ if (tx != null) tx.rollback();
+ throw e; // or display error message
+}
+finally {
+ sess.close();
+}]]></programlisting>
+
+ <para>Ou encore, avec la gestion automatique de contexte:</para>
+
+ <programlisting><![CDATA[// BMT idiom with getCurrentSession()
+try {
+ factory.getCurrentSession().beginTransaction();
+
+ // do some work
+ ...
+
+ factory.getCurrentSession().getTransaction().commit();
+}
+catch (RuntimeException e) {
+ factory.getCurrentSession().getTransaction().rollback();
+ throw e; // or display error message
+}]]></programlisting>
+
+ <para>
+ Avec CMT, la d�marcation des transactions est faite dans les descripteurs de
d�ploiement des Beans Sessions et non
+ de mani�re programmmatique, ceci r�duit le code:
+ </para>
+
+ <programlisting><![CDATA[// CMT idiom
+ Session sess = factory.getCurrentSession();
+
+ // do some work
+ ...
+]]></programlisting>
+
+ <para>
+ Dans un EJB CMT m�me le rollback intervient automatiquement, puisqu'une
<literal>RuntimeException</literal>
+ non trait�e et soulev�e par une m�thode d'un bean session indique au
conteneur d'annuler la transaction
+ globale. <emphasis>Ceci veut donc dire que vous n'avez pas �
utiliser l'API <literal>Transaction</literal> d'Hibernate
+ dans CMT.</emphasis>
+ </para>
+
+ <para>
+ Notez que le fichier de configuration Hibernate devrait contenir les valeurs
+
<literal>org.hibernate.transaction.JTATransactionFactory</literal> dans un
environnement BMT ou
+
<literal>org.hibernate.transaction.CMTTransactionFactory</literal> dans un
environnement CMT l� o� vous
+ configurez votre transaction factory Hibernate.
+ N'oubliez pas non plus de sp�cifier le param�tre
<literal>org.hibernate.transaction.manager_lookup_class</literal> .
+ De plus, assurez vous de fixez votre
<literal>hibernate.current_session_context_class</literal> soit �
<literal>"jta"</literal>
+ ou de ne pas le configurer (compatibilit� avec les versions pr�c�dentes).
+ </para>
+
+ <para>
+ La m�thode <literal>getCurrentSession()</literal> a un
inconv�nient dans les environnement JTA.
+ Il y a une astuce qui est d'utiliser un mode de lib�ration de connexion
<literal>after_statement</literal> ,
+ qui est alors utilis� par d�faut. Du � une �trange limitation de la spec JTA,
il n'est pas possible
+ pour Hibernate de nettoyer et ferme automatiquement un
<literal>ScrollableResults</literal> ouvert
+ ou une instance d'<literal>Iterator</literal> retourn�s
<literal>scroll()</literal> ou
+ <literal>iterate()</literal>. Vous
<emphasis>devez</emphasis> lib�rer le curseur base de donn�es
+ sous jacent ou invoquer
<literal>Hibernate.close(Iterator)</literal> explicitement depuis un
+ bloc <literal>finally</literal>. (Bien sur, la plupart des
applications peuvent �viter
+ d'uiliser <literal>scroll()</literal> ou
<literal>iterate()</literal> dans un code CMT.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-exceptions">
+ <title>Gestion des exceptions</title>
+
+ <para>
+ Si une <literal>Session</literal> lance une exception (incluant
les exceptions du type <literal>SQLException</literal>
+ ou d'un sous-type), vous devez imm�diatement faire le rollback de la
transaction, appeler <literal>Session.close()</literal>
+ et rel�cher les r�f�rences sur l'objet
<literal>Session</literal> . La <literal>Session</literal>
contient des m�thodes
+ pouvant la mettre dans un �tat inutilisable. Vous devez consid�rer
qu'<emphasis>aucune</emphasis>
+ exception lanc�e par Hibernate n'est traitable. Assurez-vous de fermer la
session en faisant l'appel �
+ <literal>close()</literal> dans un bloc
<literal>finally</literal> .
+ </para>
+
+ <para>
+ L'exception <literal>HibernateException</literal> , qui
englobe la plupart des exceptions pouvant survenir dans la
+ couche de persistance Hibernate, est une exception non v�rifi�e (Ceci
n'�tait pas le cas dans certaines versions ant�rieures de Hibernate.) Il est de
+ notre avis que nous ne devrions pas forcer un d�veloppeur � g�rer une
exception qu'il ne peut de toute fa�on
+ pas traiter dans une couche technique. Dans la plupart des applications, les
exceptions non v�rifi�es et les
+ exceptions fatales sont g�r�es en amont du processus (dans les couches
hautes) et un message d'erreur est
+ alors affich� � l'usager (ou un traitement alternatif est invoqu�.)
Veuillez noter qu'Hibernate peut
+ �galement lancer des exceptions non v�rifi�es d'un autre type que
<literal>HibernateException</literal> . Celles-ci sont
+ �galement non traitables et vous devez les traiter comme telles.
+ </para>
+
+ <para>
+ Hibernate englobe les <literal>SQLException</literal> s lanc�es
lors des interactions directes avec la base de donn�es
+ dans des exceptions de type: <literal>JDBCException</literal> .
En fait, Hibernate essaiera de convertir l'exception dans
+ un sous-type plus significatif de
<literal>JDBCException</literal> . L'exception
<literal>SQLException</literal> sous-jacente
+ est toujours disponible via la m�thode
<literal>JDBCException.getCause()</literal> . Cette conversion est faite par
un objet
+ de type <literal>SQLExceptionConverter</literal> , qui est
rattach� � l'objet <literal>SessionFactory</literal> .
+ Par d�faut, le <literal>SQLExceptionConverter</literal> est
associ� au dialecte de BD configur� dans Hibernate. Toutefois,
+ il est possible de fournir sa propre impl�mentation de l'interface.
(Veuillez vous r�f�rer � la javadoc sur la classe
+ <literal>SQLExceptionConverterFactory</literal> pour plus de
d�tails. Les sous-types standard de <literal>JDBCException</literal> sont:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>JDBCConnectionException</literal> - Indique une
erreur de communication avec la couche JDBC sous-jacente.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>SQLGrammarException</literal> - Indique un
probl�me de grammaire ou de syntaxe avec la requ�te SQL envoy�e.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ConstraintViolationException</literal> - Indique
une violation de contrainte d'int�grit�.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockAcquisitionException</literal> - Indique une
erreur de verrouillage lors de l'�x�cution de la requ�te.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>GenericJDBCException</literal> - Indique une
erreur g�n�rique JDBC d'une autre cat�gorie.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2 id="transactions-demarcation-timeout">
+ <title>Timeout de transaction</title>
+
+ <para>L'un des avantages fournis par les environnements transactionnels
JTA (tels les containers EJB) est la
+ gestion du timeout de transaction. La gestion des d�passements de temps de
transaction vise � s'assurer
+ qu'une transaction agissant incorrectement ne viendra pas bloquer
ind�finiment les ressources de
+ l'application. Hibernate ne peut fournir cette fonctionnalit� dans un
environnement transactionnel non-JTA.
+ Par contre, Hibernate g�re les op�rations d'acc�s aux donn�es en allouant
un temps maximal aux requ�tes pour
+ s'ex�cuter. Ainsi, une requ�te cr�ant de l'inter blocage ou
retournant de tr�s grandes quantit�s
+ d'information pourrait �tre interrompue. Dans un environnement
transactionnel JTA, Hibernate peut d�l�guer
+ au gestionnaire de transaction le soin de g�rer les d�passements de temps.
Cette fonctionnalit� est
+ abstraite par l'objet <literal>Transaction</literal> .
+ </para>
+
+ <programlisting><![CDATA[
+ Session sess = factory.openSession();
+ try {
+ //mettre le timeout � 3 secondes.
+ sess.getTransaction().setTimeout(3);
+ sess.getTransaction().begin();
+
+ // Effectuer le travail ...
+
+ sess.getTransaction().commit()
+ }
+ catch (RuntimeException e) {
+ if ( sess.getTransaction().isActive() ) {
+ sess.getTransaction().rollback();
+ }
+ throw e;
+ // ou afficher le message d'erreur.
+ }
+ finally {
+ sess.close();
+ }]]></programlisting>
+
+
+ <para>
+ Notez que <literal>setTimeout()</literal> ne peut pas �tre appel�
d'un EJB CMT, puisque le timeout
+ des transaction doit �tre sp�cifi� de mani�re d�clarative.
+ </para>
+
+ </sect2>
+
+</sect1>
+
+<sect1 id="transactions-optimistic">
+ <title>Contr�le de consurrence optimiste</title>
+
+ <para>La gestion optimiste des acc�s concurrents avec versionnage est la seule
approche pouvant garantir
+ l'extensibilit� des applications � haut niveau de charge. Le syst�me de
versionnage utilise des num�ros de
+ version ou l'horodatage pour d�tecter les mises � jour causant des conflits
avec d'autres actualisations
+ ant�rieures. Hibernate propose trois approches pour l'�criture de code
applicatif utilisant la gestion optimiste
+ d'acc�s concurrents. Le cas d'utilisation d�crit plus bas fait mention de
conversation,
+ mais le versionnage peut �galement am�liorer la qualit� d'une application en
pr�venant la perte de mises �
+ jour.</para>
+
+ <sect2 id="transactions-optimistic-manual">
+ <title>Gestion du versionnage au niveau applicatif</title>
+
+ <para>Dans cet exemple d'impl�mentation utilisant peu les
fonctionnalit�s d'Hibernate, chaque interaction avec
+ la base de donn�es se fait en utilisant une nouvelle
<literal>Session</literal> et le d�veloppeur doit recharger
+ les donn�es persistantes � partir de la BD avant de les manipuler. Cette
+ impl�mentation force l'application � v�rifier la version des objets afin
de maintenir l'isolation
+ transactionnelle. Cette approche, semblable � celle retrouv�e pour les EJB,
est la moins efficace de celles
+ pr�sent�es dans ce chapitre.
+ </para>
+
+ <programlisting>
+ <![CDATA[// foo est une instance charg�e ant�rieurement par une autre
+ Session session = factory.openSession();
+ Transaction t = session.beginTransaction();
+
+ int oldVersion = foo.getVersion();
+ session.load( foo, foo.getKey() ); // Charger l'�tat courant
+
+ if ( oldVersion != foo.getVersion() )
+ throw new StaleObjectStateException();
+
+ foo.setProperty("bar");
+ t.commit();
+ session.close();]]></programlisting>
+
+ <para>Le mapping de la propri�t� <literal>version</literal> est
fait via <literal><version></literal> et
+ Hibernate l'incr�mentera automatiquement � chaque flush() si l'entit�
doit �tre mise � jour.
+ </para>
+
+
+ <para>Bien s�r, si votre application ne fait pas face � beaucoup
d'acc�s concurrents et ne n�cessite pas
+ l'utilisation du versionnage, cette approche peut �galement �tre
utilis�e, il n'y a qu'� ignorer le code
+ reli� au versionnage. Dans ce cas, la strat�gie du
+ <emphasis>last commit wins</emphasis>
+ (litt�ralement: le dernier commit l'emporte) sera utilis�e pour les
conversations (longues transactions applicatives).
+ Gardez � l'esprit que cette approche pourrait rendre perplexe les
utilisateurs de l'application car ils
+ pourraient perdre des donn�es mises � jour sans qu'aucun message
d'erreur ne leur soit pr�sent� et sans
+ avoir la possibilit� de fusionner les donn�es.
+ </para>
+
+ <para>Il est clair que la gestion manuelle de la v�rification du
versionnage des objets ne peut �tre effectu�e
+ que dans certains cas triviaux et que cette approche n'est pas valable
pour la plupart des applications. De
+ mani�re g�n�rale, les applications ne cherchent pas � actualiser de simples
objets sans relations, elles le
+ font g�n�ralement pour de larges graphes d'objets. Pour toute application
utilisant le paradigme des conversations
+ ou des objets d�tach�s, Hibernate peut g�rer automatiquement la v�rification
des versions
+ d'objets.</para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-longsession">
+ <title>Les sessions longues et le versionnage automatique.</title>
+
+ <para>Dans ce sc�nario, une seule instance de
<literal>Session</literal> et des objets persistants est utilis�e
+ pour toute l'application. Hibernate v�rifie la version des objets
+ persistants avant d'effectuer le flush() et lance une exception si une
modification concurrente est
+ d�tect�e. Il appartient alors au d�veloppeur de g�rer l'exception. Les
traitements alternatifs g�n�ralement
+ propos�s sont alors de permettre � l'usager de faire la fusion des
donn�es ou de lui offrir de recommencer
+ son travail � partie des donn�es les plus r�centes dans la BD.
+ </para>
+
+ <para>Il est � noter que lorsqu'une application est en attente
d'une action de la part de l?usager, La <literal>Session</literal>
+ n'est pas connect�e � la couche JDBC sous-jacente. C'est la mani�re
la plus efficace de g�rer les acc�s � la
+ base de donn�es. L'application ne devrait pas se pr�occuper du
versionnage des objets, de la r�association
+ des objets d�tach�s, ni du rechargement de tous les objets � chaque
transaction.
+ </para>
+
+ <programlisting>
+ <![CDATA[// foo est une instance charg�e ant�rieurement par une autre
session
+
+ session.reconnect();// Obtention d'une nouvelle connexion JDBC
+ Transaction t = session.beginTransaction();
+ foo.setProperty("bar");
+ t.commit(); //Terminer la transaction, propager les changements et v�rifier
les versions.
+ session.disconnect(); // Retourner la connexion JDBC
+ ]]></programlisting>
+
+
+ <para>L'objet <literal>foo</literal> sait quel objet
<literal>Session</literal> l'a charg�.
<literal>Session.reconnect()</literal>
+ obtient une nouvelle connexion (celle-ci peut �tre �galement fournie) et
permet � la session de continuer
+ son travail. La m�thode <literal>Session.disconnect()</literal>
d�connecte la session de la connexion JDBC et
+ retourne celle-ci au pool de connexion (� moins que vous ne
+ lui ayez fourni vous m�me la connexion.) Apr�s la reconnexion, afin de forcer
la v�rification du versionnage
+ de certaines entit�s que vous ne cherchez pas � actualiser, vous pouvez faire
un appel � <literal>Session.lock()</literal>
+ en mode <literal>LockMode.READ</literal> pour tout objet ayant pu
�tre modifi� par une autre transaction. Il n'est pas n�cessaire de verrouiller les
+ donn�es que vous d�sirez mettre � jour.
+ </para>
+
+ <para>Si des appels implicites aux m�thodes
<literal>disconnect()</literal> et <literal>reconnect()</literal>
sont trop
+ co�teux, vous pouvez les �viter en utilisant
<literal>hibernate.connection.release_mode</literal> .
+ </para>
+
+ <para>Ce pattern peut pr�senter des probl�mes si la
<literal>Session</literal> est trop volumineuse pour �tre
+ stock�e entre les actions de l'usager. Plus sp�cifiquement, une session
<literal>HttpSession</literal> se doit
+ d'�tre la plus petite possible. Puisque la
<literal>Session</literal> joue obligatoirement le r�le de m�moire
+ cache de premier niveau et contient � ce titre tous les objets
+ charg�s, il est pr�f�rable de n'utiliser cette strat�gie que pour
quelques cycles de requ�tes car les objets
+ risquent d'y �tre rapidement p�rim�s.
+ </para>
+
+ <para>Notez que la <literal>Session</literal> d�connect�e
devrait �tre conserv�e pr�s de la couche de persistance. Autrement dit, utilisez un EJB
stateful
+ pour conserver la <literal>Session</literal> et �vitez de la
s�rialiser et de la transf�rer � la couche de pr�sentation (i.e. Il est pr�f�rable de ne
pas
+ la conserver dans la session <literal>HttpSession</literal> .)
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-detached">
+ <title>Les objets d�tach�s et le versionnage automatique</title>
+
+ <para>Chaque interaction avec le syst�me de persistance se fait via une
nouvelle <literal>Session</literal> .
+ Toutefois, les m�mes instances d'objets persistants sont r�utilis�es pour
chacune de ces interactions.
+ L'application doit pouvoir manipuler l'�tat des instances d�tach�es
ayant �t� charg�es ant�rieurement via
+ une autre session. Pour ce faire, ces objets persistants doivent �tre
rattach�s � la <literal>Session</literal>
+ courante en utilisant <literal>Session.update()</literal> ,
<literal>Session.saveOrUpdate()</literal> , ou
<literal>Session.merge()</literal> .
+ </para>
+
+ <programlisting>
+ <![CDATA[// foo est une instance charg�e ant�rieurement par une autre
session
+
+ foo.setProperty("bar");
+ session = factory.openSession();
+ Transaction t = session.beginTransaction();
+ session.saveOrUpdate(foo); //Utiliser merge() si "foo" pourrait
avoir �t� charg� pr�c�dement
+ t.commit();
+ session.close();]]> </programlisting>
+
+
+ <para>Encore une fois, Hibernate v�rifiera la version des instances devant
�tre actualis�es durant le flush().
+ Une exception sera lanc�e si des conflits sont d�tect�s.</para>
+
+ <para>Vous pouvez �galement utiliser <literal>lock()</literal>
au lieu de <literal>update()</literal> et
+ utiliser le mode <literal>LockMode.READ</literal> (qui lancera
une v�rification de version, en ignorant tous les niveaux de m�moire cache) si vous �tes
+ certain que l'objet n'a pas �t� modifi�.
+ </para>
+
+ </sect2>
+
+ <sect2 id="transactions-optimistic-customizing">
+ <title>Personnaliser le versionnage automatique</title>
+
+ <para>Vous pouvez d�sactiver l'incr�mentation automatique du num�ro de
version de certains attributs et
+ collections en mettant la valeur du param�tre de mapping
<literal>optimistic-lock</literal> �
+ false. Hibernate cessera ainsi d'incr�menter leur num�ro de version
s'ils sont mis � jour.
+ </para>
+
+ <para>Certaines entreprises poss�dent de vieux syst�mes dont les sch�mas de
bases de donn�es sont statiques et
+ ne peuvent �tre modifi�s. Il existe aussi des cas o� plusieurs applications
doivent acc�der � la m�me base
+ de donn�es, mais certaines d'entre elles ne peuvent g�rer les num�ros de
version ou les champs horodat�s.
+ Dans les deux cas, le versionnage ne peut �tre implant� par le rajout
d'une colonne dans la base de donn�es.
+ Afin de forcer la v�rification de version dans un syst�me sans en faire le
mapping, mais en for�ant une
+ comparaison des �tats de tous les attributs d'une entit�, vous pouvez
utiliser l'attribut <literal>optimistic- lock="all"</literal>
+ sous l'�l�ment <literal><class></literal> .
Veuillez noter que cette mani�re de g�rer le versionnage ne peut �tre utilis�e que si
l'application
+ utilises de longues sessions, lui permettant de comparer l'ancien �tat et
le nouvel �tat d'une entit�.
+ L'utilisation d'un pattern
<literal>session-per-request-with-detached- objects</literal> devient alors
impossible.
+ </para>
+
+ <para>Il peut �tre souhaitable de permettre les modifications concurrentes
lorsque des champs distincts sont
+ modifi�s. En mettant la propri�t�
<literal>optimistic-lock="dirty"</literal> dans l'�l�ment
<literal><class></literal> ,
+ Hibernate ne fera la comparaison que des champs devant �tre actualis�s lors
du flush().
+ </para>
+
+ <para>Dans les deux cas: en utilisant une colonne de version/horodat�e ou
via la comparaison de l'�tat complet
+ de l'objet ou de ses champs modifi�s, Hibernate ne cr�era qu'une
seule commande d'UPDATE par entit� avec la
+ clause WHERE appropri�e pour mettre � jour l'entit�
+ <emphasis>ET</emphasis>
+ en v�rifier la version. Si vous utilisez la persistance transitive pour
propager l'�v�nement de rattachement
+ � des entit�s associ�es, il est possible qu'Hibernate g�n�re des
commandes d'UPDATE inutiles. Ceci n'est
+ g�n�ralement pas un probl�me, mais certains d�clencheurs
+ <emphasis>on update</emphasis>
+ dans la base de donn�es pourraient �tre activ�s m�me si aucun changement
n'�tait r�ellement persist� sur des
+ objets associ�s. Vous pouvez personnaliser ce comportement en indiquant
<literal>select-before- update="true"</literal>
+ dans l'�l�ment de mapping
<literal><class></literal> . Ceci forcera Hibernate � faire le
SELECT de l'instance
+ afin de s'assurer que l'entit� doit r�ellement �tre
+ actualis�e avant de lancer la commande d'UPDATE.
+ </para>
+
+ </sect2>
+
+</sect1>
+
+<sect1 id="transactions-locking">
+ <title>Verouillage pessimiste</title>
+
+ <para>Il n'est n�cessaire de s'attarder � la strat�gie de verrouillage
des entit�s dans une application utilisant
+ Hibernate. Il est g�n�ralement suffisant de d�finir le niveau d'isolation
pour les connexions JDBC et de laisser
+ ensuite la base de donn�e effectuer son travail. Toutefois, certains utilisateurs
avanc�s peuvent vouloir
+ obtenir un verrouillage pessimiste exclusif sur un enregistrement et le r�obtenir
au lancement d'une nouvelle
+ transaction.</para>
+
+ <para>Hibernate utilisera toujours le m�canisme de verrouillage de la base de
donn�es et ne verrouillera jamais les
+ objets en m�moire!</para>
+
+ <para>La classe
+ <literal>LockMode</literal>
+ d�finit les diff�rents niveaux de verrouillage pouvant �tre obtenus par
Hibernate. Le verrouillage est obtenu
+ par les m�canismes suivants:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>LockMode.WRITE</literal> est obtenu automatiquement
quand Hibernate actualise ou insert un enregistrement.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.UPGRADE</literal> peut �tre obtenu de
mani�re explicite via la requ�te en utilisant
+ <literal>SELECT ... FOR UPDATE</literal> sur une base de
donn�es supportant cette syntaxe.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.UPGRADE_NOWAIT</literal> peut �tre obtenu
de mani�re explicite en utilisant
+ <literal>SELECT ... FOR UPDATE NOWAIT</literal> sur Oracle.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.READ</literal> est obtenu automatiquement
quand Hibernate lit des donn�es dans un contexte d'isolation
+ <literal>Repeatable Read</literal> ou
+ <literal>Serializable</literal> . Peut �tre r�obtenu
explicitement via une requ�te.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>LockMode.NONE</literal> repr�sente l'absence de
verouillage. Tous les objets migrent vers ce mode a la fin d'une
+ <literal>Transaction</literal> . Les objets associ�s � une
session via un appel �
+ <literal>saveOrUpdate()</literal> commencent �galement leur
cycle de vie dans cet �tat.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Les niveaux de verrouillage peuvent �tre explicitement obtenus de
l'une des mani�res suivantes:</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>Un appel �
+ <literal>Session.load()</literal> , en sp�cifiant un niveau
verrouillage
+ <literal>LockMode</literal> .
+ </para>
+ </listitem>
+ <listitem>
+ <para>Un appel �
+ <literal>Session.lock()</literal> .
+ </para>
+ </listitem>
+ <listitem>
+ <para>Une appel �
+ <literal>Query.setLockMode()</literal> .
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Si
+ <literal>Session.load()</literal>
+ est appel� avec le param�tre de niveau de verouillage
+ <literal>UPGRADE</literal>
+ ou
+ <literal>UPGRADE_NOWAIT</literal>
+ et que l'objet demand� n'est pas pr�sent dans la session, celui-ci sera
charg� � l'aide d'une requ�te
+ <literal>SELECT ... FOR UPDATE</literal>
+ . Si la m�thode
+ <literal>load()</literal>
+ est appel�e pour un objet d�j� en session avec un verrouillage moindre que celui
demand�, Hibernate appellera la
+ m�thode
+ <literal>lock()</literal>
+ pour cet objet.
+ </para>
+
+ <para>
+ <literal>Session.lock()</literal>
+ effectue une v�rification de version si le niveau de verrouillage est
+ <literal>READ</literal>
+ ,
+ <literal>UPGRADE</literal>
+ ou
+ <literal>UPGRADE_NOWAIT</literal>
+ . (Dans le cas des niveaux
+ <literal>UPGRADE</literal>
+ ou
+ <literal>UPGRADE_NOWAIT</literal>
+ , une requ�te
+ <literal>SELECT ... FOR UPDATE</literal>
+ sera utilis�e.)
+ </para>
+
+ <para>Si une base de donn�es ne supporte pas le niveau de verrouillage demand�,
Hibernate utilisera un niveau
+ alternatif convenable au lieux de lancer une exception. Ceci assurera la
portabilit� de votre
+ application.</para>
+</sect1>
+
+ <sect1 id="transactions-connection-release">
+ <title>Mode de lib�ration de Connection</title>
+
+ <para>
+ Le comportement original (2.x) d'Hibernate pour la gestion des connexions
JDBC
+ �tait que la <literal>Session</literal> obtenait une connexion
d�s qu'elle en avait
+ besoin et la lib�rait une fois la session ferm�e.
+ Hibernate 3 a introduit les modes de lib�ration de connexion pour indiquer �
la session
+ comment g�rer les transactions JDBC. Notez que la discussion suivante
n'est pertinente
+ que pour des connexions fournies par un
<literal>ConnectionProvider</literal>, celles g�r�es
+ par l'utilisateur sont en dehors du scope de cette discussion. Les
diff�rents modes
+ sont d�finies par
<literal>org.hibernate.ConnectionReleaseMode</literal>:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>ON_CLOSE</literal> - est essentiellement le
comportement pass�.
+ La session Hibernate obtient une connexion lorsqu'elle en a
besoin et la garde
+ jusqu'� ce que la session se ferme.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_TRANSACTION</literal> - indique de
relacher la connexion apr�s qu'une
+ <literal>org.hibernate.Transaction</literal> se soit
achev�e.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_STATEMENT</literal> (aussi appel�
lib�ration brutale) - indique de relacher
+ les connexions apr�s chaque ex�cution d'un statement. Ce
relachement aggressif est annul�
+ si ce statement laisse des ressources associ�es � une session donn�e
ouvertes, actuellement
+ ceci n'arrive que lors de l'utilisation de
<literal>org.hibernate.ScrollableResults</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Le param�tre de configuration
<literal>hibernate.connection.release_mode</literal> est utilis�
+ pour sp�cifier quel mode de lib�ration doit �tre utiliser. Les valeurs
possibles sont:
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>auto</literal> (valeur par d�faut) - ce choix
d�l�gue le choix de lib�ration
+ � la m�thode
<literal>org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode()</literal>
+ Pour la JTATransactionFactory, elle retourne
ConnectionReleaseMode.AFTER_STATEMENT; pour
+ JDBCTransactionFactory, elle retourne
ConnectionReleaseMode.AFTER_TRANSACTION. C'est rarement
+ une bonne id�e de changer ce comportement par d�faut puisque les
erreurs soulev�es par ce
+ param�trage tend � prouver une erreur dans le code de
l'utilisateur.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>on_close</literal> - indique d'utiliser
ConnectionReleaseMode.ON_CLOSE. Ce param�trage
+ existe pour garantir la compatibilit� avec les versions pr�c�dentes,
mais ne devrait plus �tre utilis�.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_transaction</literal> - indique
d'utiliser ConnectionReleaseMode.AFTER_TRANSACTION.
+ Ne devrait pas �tre utilis� dans les environnements JTA. Notez aussi
qu'avec
+ ConnectionReleaseMode.AFTER_TRANSACTION, si une session est
consid�r�e comme �tant en mode auto-commit
+ les connexions seront relach�es comme si le mode �tait
AFTER_STATEMENT.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>after_statement</literal> - indique
d'utiliser ConnectionReleaseMode.AFTER_STATEMENT.
+ Additonnellement, le
<literal>ConnectionProvider</literal> utilis� est consult� pour savoir
s'il supporte
+ ce param�trage
(<literal>supportsAggressiveRelease()</literal>). Si ce n'est pas le cas,
le mode de
+ lib�ration est r� initialis� �
ConnectionReleaseMode.AFTER_TRANSACTION.
+ Ce param�trage n'est s�r que dans les environnements o� il est
possible d'obtenir � nouveau
+ la m�me connexion JDBC � chaque fois que l'on fait un appel de
<literal>ConnectionProvider.getConnection()</literal>
+ ou dans les envrionnements auto-commit o� il n'est pas important
d'obtenir plusieurs fois la
+ m�me connexion.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+</chapter>
+
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/tutorial.xml (from
rev 14070, core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/tutorial.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/tutorial.xml
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/content/tutorial.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,1576 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="tutorial">
+ <title>Introduction � Hibernate</title>
+
+ <sect1 id="tutorial-intro" revision="1">
+ <title>Pr�face</title>
+
+ <para>
+ Ce chapitre est un didacticiel introductif destin� aux nouveaux utilisateurs
+ d'Hibernate. Nous commen�ons avec une simple application en ligne de
commande
+ utilisant une base de donn�es en m�moire, et la d�veloppons en �tapes
faciles
+ � comprendre.
+ </para>
+
+ <para>
+ Ce didacticiel est destin� aux nouveaux utilisateurs d'Hibernate mais
requiert
+ des connaissances Java et SQL. Il est bas� sur un didacticiel de Michael
Gloegl,
+ les biblioth�ques tierces que nous nommons sont pour les JDK 1.4 et 5.0.
Vous
+ pourriez avoir besoin d'autres biblioth�ques pour le JDK 1.3.
+ </para>
+
+ <para>
+ Le code source de ce tutoriel est inclus dans la distribution dans le
r�pertoire
+ <literal>doc/reference/tutorial/</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="tutorial-firstapp" revision="1">
+ <title>Partie 1 - Premi�re application Hibernate</title>
+
+ <para>
+ D'abord, nous cr�erons une simple application Hibernate en console. Nous
utilisons
+ une base de donn�es en m�moire (HSQL DB), donc nous n'avons pas �
installer de
+ serveur de base de donn�es.
+ </para>
+
+ <para>
+ Supposons que nous ayons besoin d'une petite application de base de
donn�es qui
+ puisse stocker des �v�nements que nous voulons suivre, et des informations �
propos
+ des h�tes de ces �v�nements.
+ </para>
+
+ <para>
+ La premi�re chose que nous faisons est de configurer notre r�pertoire de
+ d�veloppement et de mettre toutes les biblioth�ques dont nous avons besoin
dedans.
+ T�l�chargez la distribution Hibernate � partir du site web d'Hibernate.
+ Extrayez le paquet et placez toutes les biblioth�ques requises trouv�es dans
+ <literal>/lib</literal> dans le r�pertoire
<literal>/lib</literal> de votre
+ nouveau r�pertoire de travail. Il devrait ressembler � �a :
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ antlr.jar
+ cglib-full.jar
+ asm.jar
+ asm-attrs.jars
+ commons-collections.jar
+ commons-logging.jar
+ ehcache.jar
+ hibernate3.jar
+ jta.jar
+ dom4j.jar
+ log4j.jar ]]></programlisting>
+
+ <para>
+ Ceci est l'ensemble minimum de biblioth�ques requises (notez que nous
avons aussi
+ copi� hibernate3.jar, l'archive principale) pour Hibernate. Lisez le
fichier
+ <literal>README.txt</literal> dans le r�pertoire
<literal>lib/</literal> de la
+ distribution Hibernate pour plus d'informations � propos des bilioth�ques
tierces
+ requises et optionnelles. (En fait, log4j n'est pas requis mais pr�f�r�
par beaucoup
+ de d�veloppeurs.)
+ </para>
+
+ <para>
+ Ensuite, nous cr�ons une classe qui r�pr�sente l'�v�nement que nous
voulons
+ stocker dans notre base de donn�es.
+ </para>
+
+ <sect2 id="tutorial-firstapp-firstclass" revision="1">
+ <title>La premi�re classe</title>
+
+ <para>
+ Notre premi�re classe persistante est une simple classe JavaBean avec
+ quelques propri�t�s :
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+import java.util.Date;
+
+public class Event {
+ private Long id;
+
+ private String title;
+ private Date date;
+
+ public Event() {}
+
+ public Long getId() {
+ return id;
+ }
+
+ private void setId(Long id) {
+ this.id = id;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}]]></programlisting>
+
+ <para>
+ Vous pouvez voir que cette classe utilise les conventions de nommage
standard JavaBean
+ pour les m�thodes getter/setter des propri�t�s, ainsi qu'une
visibilit� priv�e
+ pour les champs. Ceci est la conception recommand�e - mais pas
obligatoire. Hibernate peut
+ aussi acc�der aux champs directement, le b�n�fice des m�thodes
d'acc�s est la robustesse
+ pour la refonte de code. Le constructeur sans argument est requis pour
instancier
+ un objet de cette classe via reflexion.
+ </para>
+
+ <para>
+ La propri�t� <literal>id</literal> contient la valeur
d'un identifiant unique pour un
+ �v�nement particulier. Toutes les classes d'entit�s persistantes
(ainsi que les classes
+ d�pendantes de moindre importance) auront besoin d'une telle
propri�t� identifiante si nous
+ voulons utiliser l'ensemble complet des fonctionnalit�s
d'Hibernate. En fait, la plupart des
+ applications (surtout les applications web) ont besoin de distinguer des
objets par des
+ identifiants, donc vous devriez consid�rer �a comme une fonctionnalit�
plut�t que comme une
+ limitation. Cependant, nous ne manipulons g�n�ralement pas l'identit�
d'un objet, dor�navant
+ la m�thode setter devrait �tre priv�e. Seul Hibernate assignera les
identifiants lorsqu'un
+ objet est sauvegard�. Vous pouvez voir qu'Hibernate peut acc�der aux
m�thodes publiques,
+ priv�es et prot�g�es, ainsi qu'aux champs (publics, priv�s, prot�g�s)
directement. Le choix
+ vous est laiss�, et vous pouvez l'ajuster � la conception de votre
application.
+ </para>
+
+ <para>
+ Le constructeur sans argument est requis pour toutes les classes
persistantes ;
+ Hibernate doit cr�er des objets pour vous en utilisant la r�flexion Java.
Le
+ constructeur peut �tre priv�, cependant, la visibilit� du paquet est
requise
+ pour la g�n�ration de proxy � l'ex�cution et une r�cup�ration des
donn�es efficaces
+ sans instrumentation du bytecode.
+ </para>
+
+ <para>
+ Placez ce fichier source Java dans un r�pertoire appel�
<literal>src</literal>
+ dans le dossier de d�veloppement. Ce r�pertoire devrait maintenant
ressembler
+ � �a :
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate et biblioth�ques tierces>
++src
+ +events
+ Event.java]]></programlisting>
+
+
+ <para>
+ Dans la prochaine �tape, nous informons Hibernate de cette classe
persistante.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-mapping" revision="1">
+ <title>Le fichier de mapping</title>
+
+ <para>
+ Hibernate a besoin de savoir comment charger et stocker des objets
d'une classe
+ persistante. C'est l� qu'intervient le fichier de mapping
Hibernate. Le fichier
+ de mapping indique � Hibernate � quelle table dans la base de donn�es il
doit
+ acc�der, et quelles colonnes de cette table il devra utiliser.
+ </para>
+
+ <para>
+ La structure basique de ce fichier de mapping ressemble � �a :
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+[...]
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Notez que la DTD Hibernate est tr�s sophistiqu�e. Vous pouvez
l'utiliser
+ pour l'auto-compl�tement des �l�ments et des attributs de mapping XML
dans
+ votre �diteur ou votre IDE. Vous devriez aussi ouvrir le fichier DTD
dans
+ votre �diteur de texte - c'est le moyen le plus facile d'obtenir
une vue
+ d'ensemble de tous les �l�ments et attributs, et de voir les valeurs
par
+ d�faut, ainsi que quelques commentaires. Notez qu'Hibernate ne
chargera
+ pas le fichier DTD � partir du web, mais regardera d'abord dans le
classpath
+ de l'application. Le fichier DTD est inclus dans
<literal>hibernate3.jar</literal>
+ ainsi que dans le r�pertoire <literal>src</literal> de la
distribution
+ Hibernate.
+ </para>
+
+ <para>
+ Nous omettrons la d�claration de la DTD dans les exemples futurs pour
+ raccourcir le code. Bien s�r il n'est pas optionnel.
+ </para>
+
+ <para>
+ Entre les deux balises <literal>hibernate-mapping</literal>,
incluez un
+ �l�ment <literal>class</literal>. Toutes les classes
d'entit�s persistantes
+ (encore une fois, il pourrait y avoir des classes d�pendantes plus tard,
+ qui ne sont pas des entit�s m�re) ont besoin d'un mapping vers une
table
+ de la base de donn�es SQL :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Event" table="EVENTS">
+
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Plus loin, nous disons � Hibernate comment persister et charger un objet
de la classe
+ <literal>Event</literal> dans la table
<literal>EVENTS</literal>, chaque instance est
+ repr�sent�e par une ligne dans cette table. Maintenant nous continuons
avec le mapping de
+ la propri�t� de l'identifiant unique vers la clef primaire de la
table. De plus, comme
+ nous ne voulons pas nous occuper de la gestion de cet identifiant, nous
utilisons une
+ strat�gie de g�n�ration d'identifiant d'Hibernate pour la colonne
de la clef primaire
+ subrog�e :
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="increment"/>
+ </id>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ L'�l�ment <literal>id</literal> est la d�claration de la
propri�t� de l'identifiant,
+ <literal>name="id"</literal> d�clare le nom de la
propri�t� Java - Hibernate
+ utilisera les m�thodes getter et setter pour acc�der � la propri�t�.
L'attribut
+ <literal>column</literal> indique � Hibernate quelle colonne
de la table
+ <literal>EVENTS</literal> nous utilisons pour cette clef
primaire. L'�l�ment
+ <literal>generator</literal> imbriqu� sp�cifie la strat�gie
de g�n�ration de
+ l'identifiant, dans ce cas nous avons utilis�
<literal>increment</literal>,
+ laquelle est une m�thode tr�s simple utile surtout pour les tests
+ (et didacticiels). Hibernate supporte aussi les identifiants g�n�r�s par
les
+ bases de donn�es, globalement uniques, ainsi que les identifiants
assign�s par
+ l'application (ou n'importe quelle strat�gie que vous avez �crit
en extension).
+ </para>
+
+ <para>
+ Finalement nous incluons des d�clarations pour les propri�t�s
persistantes de la classe
+ dans le fichier de mapping. Par d�faut, aucune propri�t� de la classe
n'est consid�r�e
+ comme persistante :
+ </para>
+
+ <programlisting><![CDATA[
+<hibernate-mapping>
+
+ <class name="Event" table="EVENTS">
+ <id name="id" column="EVENT_ID">
+ <generator class="increment"/>
+ </id>
+ <property name="date" type="timestamp"
column="EVENT_DATE"/>
+ <property name="title"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Comme avec l'�l�ment <literal>id</literal>,
l'attribut <literal>name</literal>
+ de l'�l�ment <literal>property</literal> indique �
Hibernate quels getters/setters
+ utiliser.
+ </para>
+
+ <para>
+ Pourquoi le mapping de la propri�t� <literal>date</literal>
inclut
+ l'attribut <literal>column</literal>, mais pas
<literal>title</literal> ?
+ Sans l'attribut <literal>column</literal> Hibernate
utilise par d�faut
+ le nom de la propri�t� comme nom de colonne. Ca fonctionne bien pour
+ <literal>title</literal>. Cependant,
<literal>date</literal> est un mot clef
+ r�serv� dans la plupart des bases de donn�es, donc nous utilisons un nom
+ diff�rent pour le mapping.
+ </para>
+
+ <para>
+ La prochaine chose int�ressante est que le mapping de
<literal>title</literal>
+ manque aussi d'un attribut <literal>type</literal>. Les
types que nous d�clarons
+ et utilisons dans les fichiers de mapping ne sont pas, comme vous
pourriez vous
+ y attendre, des types de donn�es Java. Ce ne sont pas, non plus, des
types de
+ base de donn�es SQL. Ces types sont donc appel�s des
<emphasis>types de mapping
+ Hibernate</emphasis>, des convertisseurs qui peuvent traduire des
types Java en
+ types SQL et vice versa. De plus, Hibernate tentera de d�terminer la
bonne conversion
+ et le type de mapping lui-m�me si l'attribut
<literal>type</literal> n'est pas
+ pr�sent dans le mapping. Dans certains cas, cette d�tection automatique
(utilisant
+ la r�flexion sur la classe Java) pourrait ne pas donner la valeur
attendue ou
+ dont vous avez besoin. C'est le cas avec la propri�t�
<literal>date</literal>.
+ Hibernate ne peut pas savoir si la propri�t� "mappera" une
colonne SQL de type
+ <literal>date</literal>,
<literal>timestamp</literal> ou <literal>time</literal>.
+ Nous d�clarons que nous voulons conserver des informations avec une date
compl�te
+ et l'heure en mappant la propri�t� avec un
<literal>timestamp</literal>.
+ </para>
+
+ <para>
+ Ce fichier de mapping devrait �tre sauvegard� en tant que
<literal>Event.hbm.xml</literal>,
+ juste dans le r�pertoire � c�t� du fichier source de la classe Java
<literal>Event</literal>.
+ Le nommage des fichiers de mapping peut �tre arbitraire, cependant le
suffixe
+ <literal>hbm.xml</literal> est devenu une convention dans la
communaut� des
+ d�veloppeurs Hibernate. La structure du r�pertoire devrait ressembler �
�a :
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate et biblioth�ques tierces>
++src
+ Event.java
+ Event.hbm.xml]]></programlisting>
+
+ <para>
+ Nous poursuivons avec la configuration principale d'Hibernate.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-configuration"
revision="1">
+ <title>Configuration d'Hibernate</title>
+
+ <para>
+ Nous avons maintenant une classe persistante et son fichier de mapping.
Il est temps de
+ configurer Hibernate. Avant �a, nous avons besoin d'une base de
donn�es. HSQL DB, un
+ SGBD SQL bas� sur Java et travaillant en m�moire, peut �tre t�l�charg� �
partir du site
+ web de HSQL. En fait, vous avez seulement besoin de
<literal>hsqldb.jar</literal>. Placez
+ ce fichier dans le r�pertoire <literal>lib/</literal> du
dossier de d�veloppement.
+ </para>
+
+ <para>
+ Cr�ez un r�pertoire appel� <literal>data</literal> � la
racine du r�pertoire de d�veloppement -
+ c'est l� que HSQL DB stockera ses fichiers de donn�es. D�marrez
maintenant votre base de donn�es
+ en ex�cutant <literal>java -classpath lib/hsqldb.jar
org.hsqldb.Server</literal> dans votre r�pertoire de travail.
+ Vous observez qu'elle d�marre et ouvre une socket TCP/IP, c'est
l� que notre application
+ se connectera plus tard. Si vous souhaitez d�marrez � partir d'une
nouvelle base de donn�es
+ pour ce tutoriel (faites <literal>CTRL + C</literal> dans la
fen�tre the window), effacez
+ le r�pertoire <literal>data/</literal> et red�marrez HSQL DB
� nouveau.
+
+ </para>
+
+ <para>
+ Hibernate est la couche de votre application qui se connecte � cette base
de donn�es,
+ donc il a besoin des informations de connexion. Les connexions sont
�tablies � travers
+ un pool de connexions JDBC, que nous devons aussi configurer. La
distribution Hibernate
+ contient diff�rents outils de gestion de pools de connexions JDBC open
source, mais
+ pour ce didacticiel nous utiliserons le pool de connexions int�gr� �
Hibernate. Notez
+ que vous devez copier les biblioth�ques requises dans votre classpath et
utiliser
+ une configuration de pool de connexions diff�rente si vous voulez
utiliser
+ un logiciel de gestion de pools JDBC tiers avec une qualit� de
production.
+ </para>
+
+ <para>
+ Pour la configuration d'Hibernate, nous pouvons utiliser un simple
fichier
+ <literal>hibernate.properties</literal>, un fichier
<literal>hibernate.cfg.xml</literal>
+ l�g�rement plus sophistiqu�, ou m�me une configuration compl�te par
programmation. La
+ plupart des utilisateurs pr�f�rent le fichier de configuration XML :
+ </para>
+
+ <programlisting><![CDATA[<?xml version='1.0'
encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+ <session-factory>
+
+ <!-- Database connection settings -->
+ <property
name="connection.driver_class">org.hsqldb.jdbcDriver</property>
+ <property
name="connection.url">jdbc:hsqldb:hsql://localhost</property>
+ <property name="connection.username">sa</property>
+ <property name="connection.password"></property>
+
+ <!-- JDBC connection pool (use the built-in) -->
+ <property name="connection.pool_size">1</property>
+
+ <!-- SQL dialect -->
+ <property
name="dialect">org.hibernate.dialect.HSQLDialect</property>
+
+ <!-- Enable Hibernate's automatic session context management -->
+ <property
name="current_session_context_class">thread</property>
+
+ <!-- Disable the second-level cache -->
+ <property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
+
+ <!-- Echo all executed SQL to stdout -->
+ <property name="show_sql">true</property>
+
+ <!-- Drop and re-create the database schema on startup -->
+ <property name="hbm2ddl.auto">create</property>
+
+ <mapping resource="events/Event.hbm.xml"/>
+
+ </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+ <para>
+ Notez que cette configuration XML utilise une DTD diff�rente. Nous
configurons
+ une <literal>SessionFactory</literal> d'Hibernate - une
fabrique globale responsable
+ d'une base de donn�es particuli�re. Si vous avez plusieurs base de
donn�es, utilisez
+ plusieurs configurations
<literal><session-factory></literal>, g�n�ralement
+ dans des fichiers de configuration diff�rents (pour un d�marrage plus
facile).
+ </para>
+
+ <para>
+ Les quatre premiers �l�ments <literal>property</literal>
contiennent la configuration
+ n�cessaire pour la connexion JDBC. L'�l�ment
<literal>property</literal> du dialecte
+ sp�cifie quelle variante du SQL Hibernate va g�n�rer. La gestion
automatique des sessions
+ d'Hibernate pour les contextes de persistance sera d�taill�e tr�s
vite.
+ L'option <literal>hbm2ddl.auto</literal> active la
g�n�ration automatique des sch�mas de
+ base de donn�es - directement dans la base de donn�es. Cela peut bien s�r
aussi �tre
+ d�sactiv� (en supprimant l'option de configuration) ou redirig� vers
un fichier avec
+ l'aide de la t�che Ant <literal>SchemaExport</literal>.
Finalement, nous ajoutons
+ le(s) fichier(s) de mapping pour les classes persistantes.
+ </para>
+
+ <para>
+ Copiez ce fichier dans le r�pertoire source, il terminera dans la racine
+ du classpath. Hibernate cherchera automatiquement, au d�marrage, un
fichier appel�
+ <literal>hibernate.cfg.xml</literal> dans la racine du
classpath.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-ant" revision="1">
+ <title>Construction avec Ant</title>
+
+ <para>
+ Nous allons maintenant construire le didacticiel avec Ant. Vous aurez
besoin d'avoir Ant
+ d'install� - r�cup�rez-le � partir de <ulink
url="http://ant.apache.org/bindownload.cgi"> la page
+ de t�l�chargement de Ant</ulink>. Comment installer Ant ne sera pas
couvert ici. R�f�rez-vous
+ au <ulink
url="http://ant.apache.org/manual/index.html">manuel d'Ant</ulink>.
Apr�s que
+ vous aurez install� Ant, nous pourrons commencer � cr�er le fichier de
construction. Il
+ s'appellera <literal>build.xml</literal> et sera plac�
directement dans le r�pertoire de
+ d�veloppement.
+ </para>
+
+ <para>
+ Un fichier de construction basique ressemble � �a :
+ </para>
+
+ <programlisting><![CDATA[<project
name="hibernate-tutorial" default="compile">
+
+ <property name="sourcedir" value="${basedir}/src"/>
+ <property name="targetdir" value="${basedir}/bin"/>
+ <property name="librarydir" value="${basedir}/lib"/>
+
+ <path id="libraries">
+ <fileset dir="${librarydir}">
+ <include name="*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="clean">
+ <delete dir="${targetdir}"/>
+ <mkdir dir="${targetdir}"/>
+ </target>
+
+ <target name="compile" depends="clean, copy-resources">
+ <javac srcdir="${sourcedir}"
+ destdir="${targetdir}"
+ classpathref="libraries"/>
+ </target>
+
+ <target name="copy-resources">
+ <copy todir="${targetdir}">
+ <fileset dir="${sourcedir}">
+ <exclude name="**/*.java"/>
+ </fileset>
+ </copy>
+ </target>
+
+</project>]]></programlisting>
+
+ <para>
+ Cela dira � Ant d'ajouter tous les fichiers du r�pertoire lib
finissant par
+ <literal>.jar</literal> dans le classpath utilis� pour la
compilation. Cela copiera aussi
+ tous les fichiers source non Java dans le r�pertoire cible, par exemple
les fichiers de
+ configuration et de mapping d'Hibernate. Si vous lancez Ant
maintenant, vous devriez
+ obtenir cette sortie :
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant
+Buildfile: build.xml
+
+copy-resources:
+ [copy] Copying 2 files to C:\hibernateTutorial\bin
+
+compile:
+ [javac] Compiling 1 source file to C:\hibernateTutorial\bin
+
+BUILD SUCCESSFUL
+Total time: 1 second ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-helpers" revision="3">
+ <title>D�marrage et aides</title>
+
+ <para>
+ Il est temps de charger et de stocker quelques objets
<literal>Event</literal>,
+ mais d'abord nous devons compl�ter la configuration avec du code
+ d'infrastructure. Nous devons d�marrer Hibernate. Ce d�marrage inclut
la construction
+ d'un objet <literal>SessionFactory</literal> global et le
stocker quelque part
+ facile d'acc�s dans le code de l'application. Une
<literal>SessionFactory</literal>
+ peut ouvrir des nouvelles <literal>Session</literal>s. Une
<literal>Session</literal>
+ repr�sente une unit� de travail simplement "thread�e", la
<literal>SessionFactory</literal>
+ est un objet global "thread-safe", instanci� une seule fois.
+ </para>
+
+ <para>
+ Nous cr�erons une classe d'aide
<literal>HibernateUtil</literal> qui s'occupe du
+ d�marrage et rend la gestion des <literal>Session</literal>s
plus facile.
+ Regardons l'impl�mentation :
+ </para>
+
+ <programlisting><![CDATA[package util;
+
+import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+ public static final SessionFactory sessionFactory;
+
+ static {
+ try {
+ // Cr�ation de la SessionFactory � partir de hibernate.cfg.xml
+ sessionFactory = new Configuration().configure().buildSessionFactory();
+ } catch (Throwable ex) {
+ // Make sure you log the exception, as it might be swallowed
+ System.err.println("Initial SessionFactory creation failed." +
ex);
+ throw new ExceptionInInitializerError(ex);
+ }
+ }
+
+ public static final ThreadLocal session = new ThreadLocal();
+
+ public static SessionFactory getSessionFactory() {
+ return sessionFactory;
+ }
+}]]></programlisting>
+
+ <para>
+ Cette classe ne produit pas seulement la
<literal>SessionFactory</literal> globale
+ dans un initialiseur statique (appel� une seule fois par la JVM lorsque
la classe
+ est charg�e), elle masque le fait qu'elle exploite un singleton. Elle
pourrait aussi
+ obtenir la <literal>SessionFactory</literal> depuis JNDI dans
un serveur d'applications.
+ </para>
+
+ <para>
+ Si vous nommez la <literal>SessionFactory</literal> dans
votre fichier de configuration,
+ Hibernate tentera la r�cup�ration depuis JNDI. Pour �viter ce code, vous
pouvez aussi
+ utiliser un d�ploiement JMX et laisser le conteneur (compatible JMX)
instancier et lier
+ un <literal>HibernateService</literal> � JNDI. Ces options
avanc�es sont d�taill�es dans
+ la documentation de r�f�rence Hibernate.
+ </para>
+
+ <para>
+ Placez <literal>HibernateUtil.java</literal> dans le
r�pertoire source de d�veloppement,
+ et ensuite <literal>Event.java</literal> :
+ </para>
+
+ <programlisting><![CDATA[.
++lib
+ <Hibernate and third-party libraries>
++src
+ +events
+ Event.java
+ Event.hbm.xml
+ +util
+ HibernateUtil.java
+ hibernate.cfg.xml
++data
+build.xml]]></programlisting>
+
+ <para>
+ Cela devrait encore compiler sans probl�me. Nous avons finalement besoin
de configurer
+ le syst�me de "logs" - Hibernate utilise commons-logging et
vous laisse le choix entre
+ log4j et le syst�me de logs du JDK 1.4. La plupart des d�veloppeurs
pr�f�rent log4j :
+ copiez <literal>log4j.properties</literal> de la distribution
d'Hibernate (il est dans
+ le r�pertoire <literal>etc/</literal>) dans votre r�pertoire
<literal>src</literal>,
+ puis faites de m�me avec
<literal>hibernate.cfg.xml</literal>. Regardez la configuration
+ d'exemple et changez les param�tres si vous voulez une sortie plus
verbeuse. Par d�faut,
+ seul le message de d�marrage d'Hibernate est affich� sur la sortie
standard.
+ </para>
+
+ <para>
+ L'infrastructure de ce didacticiel est compl�te - et nous sommes
pr�ts � effectuer un
+ travail r�el avec Hibernate.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-firstapp-workingpersistence"
revision="4">
+ <title>Charger et stocker des objets</title>
+
+ <para>
+ Finalement nous pouvons utiliser Hibernate pour charger et stocker des
objets.
+ Nous �crivons une classe <literal>EventManager</literal> avec
une m�thode
+ <literal>main()</literal> :
+ </para>
+
+ <programlisting><![CDATA[package events;
+import org.hibernate.Session;
+
+import java.util.Date;
+
+import util.HibernateUtil;
+
+public class EventManager {
+
+ public static void main(String[] args) {
+ EventManager mgr = new EventManager();
+
+ if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+ }
+
+ HibernateUtil.getSessionFactory().close();
+ }
+
+ private void createAndStoreEvent(String title, Date theDate) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ session.save(theEvent);
+
+ session.getTransaction().commit();
+ }]]></programlisting>
+
+ <para>
+ Nous cr�ons un nouvel objet <literal>Event</literal>, et le
remettons � Hibernate.
+ Hibernate s'occupe maintenant du SQL et ex�cute les
<literal>INSERT</literal>s
+ dans la base de donn�es. Regardons le code de gestion de la
<literal>Session</literal>
+ et de la <literal>Transaction</literal> avant de lancer �a.
+ </para>
+
+ <para>
+ Une <literal>Session</literal> est une unit� de travail. Pour
le moment, nous allons faire
+ les choses simplement et assumer une granularit� un-un entre une
<literal>Session</literal>
+ hibernate et une transaction � la base de donn�es. Pour isoler notre code
du syst�me de transaction
+ sous-jacent (dans notre cas, du pure JDBC, mais cela pourrait �tre JTA),
nous utilisons l'API
+ <literal>Transaction</literal> qui est disponible depuis la
<literal>Session</literal> Hibernate.
+ </para>
+
+ <para>
+ Que fait
<literal>sessionFactory.getCurrentSession()</literal> ? Premi�rement, vous
pouvez
+ l'invoquer autant de fois que vous le voulez et n'importe o� du
moment que vous avez votre
+ <literal>SessionFactory</literal> (facile gr�ce �
<literal>HibernateUtil</literal>).
+ La m�thode <literal>getCurrentSession()</literal> renvoie
toujours l'unit� de travail courante.
+ Souvenez vous que nous avons bascul� notre option de configuration au
m�canisme bas� sur le "thread"
+ dans <literal>hibernate.cfg.xml</literal>. Par cons�quent, le
scope de l'unit� de travail
+ courante est le thread java courant d'ex�cution. Ceci n'est pas
totalement vrai. Une
+ <literal>Session</literal> commence lorsqu'elle est
vraiment utilis�e la premi�re fois,
+ Lorsque nous appelons pour la premi�re fois
<literal>getCurrentSession()</literal>.
+ Ensuite, elle est li�e, par Hibernate, au thread courant. Lorsque la
transaction s'ach�ve
+ (commit ou rollback), Hibernate d�lie la
<literal>Session</literal> du thread et la ferme
+ pour vous. Si vous invoquez
<literal>getCurrentSession()</literal> une autre fois, vous obtenez
+ une nouvelle <literal>Session</literal> et pouvez entamer une
nouvelle unit� de travail.
+ Ce mod�le de programmation
"<emphasis>thread-bound</emphasis>" est le moyen le plus
+ populaire d'utiliser Hibernate.
+ </para>
+
+ <para>
+ Lisez <xref linkend="transactions"/> pour plus
d'informations sur la gestion des transactions et leur d�marcations.
+ Nous n'avons pas g�r� les erreurs et rollback sur l'exemple
pr�c�dent.
+ </para>
+
+ <para>
+ Pour lancer cette premi�re routine, nous devons ajouter une cible
appelable dans
+ le fichier de construction de Ant :
+ </para>
+
+ <programlisting><![CDATA[<target name="run"
depends="compile">
+ <java fork="true" classname="events.EventManager"
classpathref="libraries">
+ <classpath path="${targetdir}"/>
+ <arg value="${action}"/>
+ </java>
+</target>]]></programlisting>
+
+ <para>
+ La valeur de l'argument <literal>action</literal>
correspond � la ligne de commande
+ qui appelle la cible :
+ </para>
+
+ <programlisting><![CDATA[C:\hibernateTutorial\>ant run
-Daction=store]]></programlisting>
+
+ <para>
+ Vous devriez voir, apr�s la compilation, Hibernate d�marrer et, en
fonction de votre
+ configuration, beaucoup de traces sur la sortie. � la fin vous trouverez
la ligne suivante :
+ </para>
+
+ <programlisting><![CDATA[[java] Hibernate: insert into EVENTS
(EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
+
+ <para>
+ C'est l'<literal>INSERT</literal> ex�cut� par
Hibernate, les points d'interrogation
+ repr�sentent les param�tres JDBC li�s. Pour voir les valeurs li�es aux
arguments, ou
+ pour r�duire la verbosit� des traces, v�rifier votre
<literal>log4j.properties</literal>.
+ </para>
+
+ <para>
+ Maintenant nous aimerions aussi lister les �v�nements stock�s, donc nous
ajoutons une
+ option � la m�thode principale :
+ </para>
+
+ <programlisting><![CDATA[if (args[0].equals("store")) {
+ mgr.createAndStoreEvent("My Event", new Date());
+}
+else if (args[0].equals("list")) {
+ List events = mgr.listEvents();
+ for (int i = 0; i < events.size(); i++) {
+ Event theEvent = (Event) events.get(i);
+ System.out.println("Event: " + theEvent.getTitle() +
+ " Time: " + theEvent.getDate());
+ }
+}]]></programlisting>
+
+ <para>
+ Nous ajoutons aussi une nouvelle m�thode
<literal>listEvents()</literal> :
+ </para>
+
+ <programlisting><![CDATA[private List listEvents() {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+ session.beginTransaction();
+
+ List result = session.createQuery("from Event").list();
+
+ session.getTransaction().commit();
+
+ return result;
+}]]></programlisting>
+
+ <para>
+ Ce que nous faisons ici c'est utiliser une requ�te HQL (Hibernate
Query Language) pour
+ charger tous les objets <literal>Event</literal> existants de
la base de donn�es.
+ Hibernate g�n�rera le SQL appropri�, l'enverra � la base de donn�es
et peuplera des
+ objets <literal>Event</literal> avec les donn�es. Vous pouvez
cr�er des requ�tes plus
+ complexes avec HQL, bien s�r.
+ </para>
+
+ <para>
+ Maintenant, pour ex�cuter et tester tout �a, suivez ces �tapes :
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Ex�cutez <literal>ant run -Daction=store</literal>
pour stocker quelque
+ chose dans la base de donn�es et, bien s�r, pour g�n�rer, avant,
le sch�ma
+ de la base de donn�es gr�ce � hbm2ddl.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Maintenant d�sactivez hbm2ddl en commentant la propri�t� dans
votre fichier
+ <literal>hibernate.cfg.xml</literal>. G�n�ralement
vous la laissez seulement
+ activ�e dans des tests unitaires en continu, mais une autre
ex�cution de hbm2ddl
+ <emphasis>effacerait</emphasis> tout ce que vous avez
stock� - le param�tre de
+ configuration <literal>create</literal> se traduit en
fait par "supprimer toutes les
+ tables du sch�ma, puis re-cr�er toutes les tables, lorsque la
SessionFactory est
+ construite".
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Si maintenant vous appelez Ant avec
<literal>-Daction=list</literal>, vous devriez voir
+ les �v�nements que vous avez stock�s jusque l�. Vous pouvez bien s�r
aussi appeler l'action
+ <literal>store</literal> plusieurs fois.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-associations">
+ <title>Partie 2 - Mapper des associations</title>
+
+ <para>
+ Nous avons mapp� une classe d'une entit� persistante vers une table.
Partons de l� et
+ ajoutons quelques associations de classe. D'abord nous ajouterons des
gens � notre
+ application, et stockerons une liste d'�v�nements auxquels ils
participent.
+ </para>
+
+ <sect2 id="tutorial-associations-mappinguser"
revision="1">
+ <title>Mapper la classe Person</title>
+
+ <para>
+ La premi�re version de la classe <literal>Person</literal>
est simple :
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+public class Person {
+
+ private Long id;
+ private int age;
+ private String firstname;
+ private String lastname;
+
+ public Person() {}
+
+ // Accessor methods for all properties, private setter for 'id'
+
+}]]></programlisting>
+
+ <para>
+ Cr�ez un nouveau fichier de mapping appel�
<literal>Person.hbm.xml</literal>
+ (n'oubliez pas la r�f�rence � la DTD)
+ </para>
+
+ <programlisting><![CDATA[<hibernate-mapping>
+
+ <class name="events.Person" table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+ </class>
+
+</hibernate-mapping>]]></programlisting>
+
+ <para>
+ Finalement, ajoutez la nouveau mapping � la configuration d'Hibernate
:
+ </para>
+
+ <programlisting><![CDATA[<mapping
resource="events/Event.hbm.xml"/>
+<mapping resource="events/Person.hbm.xml"/>]]></programlisting>
+ <para>
+ Nous allons maintenant cr�er une association entre ces deux entit�s.
�videmment,
+ des personnes peuvent participer aux �v�nements, et des �v�nements ont
des participants.
+ Les questions de conception que nous devons traiter sont : direction,
cardinalit� et comportement
+ de la collection.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-unidirset"
revision="2">
+ <title>Une association unidirectionnelle bas�e sur Set</title>
+
+ <para>
+ Nous allons ajouter une collection d'�v�nements � la classe
<literal>Person</literal>. De
+ cette mani�re nous pouvons facilement naviguer dans les �v�nements
d'une personne
+ particuli�re, sans ex�cuter une requ�te explicite - en appelant
+ <literal>aPerson.getEvents()</literal>. Nous utilisons une
collection Java, un
+ <literal>Set</literal>, parce que la collection ne contiendra
pas d'�l�ments dupliqu�s et
+ l'ordre ne nous importe pas.
+ </para>
+
+ <para>
+ Nous avons besoin d'une association unidirectionnelle, pluri-valu�e,
impl�ment�e avec
+ un <literal>Set</literal>. �crivons le code pour �a dans les
classes Java et mappons les :
+ </para>
+
+ <programlisting><![CDATA[public class Person {
+
+ private Set events = new HashSet();
+
+ public Set getEvents() {
+ return events;
+ }
+
+ public void setEvents(Set events) {
+ this.events = events;
+ }
+}]]></programlisting>
+
+ <para>
+ D'abord nous mappons cette association, mais pensez � l'autre
c�t�. Clairement, nous pouvons
+ la laisser unidirectionnelle. Ou alors, nous pourrions cr�er une autre
collection sur
+ <literal>Event</literal>, si nous voulons �tre capable de la
parcourir de mani�re
+ bidirectionnelle, c'est-�-dire avoir
<literal>anEvent.getParticipants()</literal>.
+ Ce n'est pas n�cessaire d'un point de vue fonctionnel. Vous
pourrez toujours ex�cuter une requ�te
+ explicite pour r�cup�rer les participants d'un "event"
particulier. Ce choix de conception
+ vous est laiss�, mais ce qui reste certains est la cardinalit� de
l'association: "plusieurs"
+ des deux c�t�s, nous appelons cela une association
<emphasis>many-to-many</emphasis>.
+ Par cons�quent nous utilisons un mapping Hibernate many-to-many:
+ </para>
+
+ <programlisting><![CDATA[<class name="events.Person"
table="PERSON">
+ <id name="id" column="PERSON_ID">
+ <generator class="native"/>
+ </id>
+ <property name="age"/>
+ <property name="firstname"/>
+ <property name="lastname"/>
+
+ <set name="events" table="PERSON_EVENT">
+ <key column="PERSON_ID"/>
+ <many-to-many column="EVENT_ID" class="Event"/>
+ </set>
+
+</class>]]></programlisting>
+
+ <para>
+ Hibernate supporte toutes sortes de mapping de collection, un
<literal><set></literal>
+ �tant le plus commun. Pour une association many-to-many (ou une relation
+ d'entit� <emphasis>n:m</emphasis>), une table
d'association est requise. Chaque ligne dans cette table repr�sente un lien entre une
personne et un �v�nement. Le nom de la table est
+ configur� avec l'attribut <literal>table</literal> de
l'�l�ment <literal>set</literal>. Le
+ nom de la colonne identifiant dans l'association, du c�t� de la
personne, est d�fini avec
+ l'�l�ment <literal><key></literal>, et le
nom de la colonne pour l'�v�nement dans
+ l'attribut <literal>column</literal> de
<literal><many-to-many></literal>. Vous
+ devez aussi donner � Hibernate la classe des objets de votre collection
(c'est-�-dire : la
+ classe de l'autre c�t� de la collection).
+ </para>
+
+ <para>
+ Le sch�ma de base de donn�es pour ce mapping est donc :
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | |
+ |_____________| |__________________| | PERSON |
+ | | | | |_____________|
+ | *EVENT_ID | <--> | *EVENT_ID | | |
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
+ | TITLE | |__________________| | AGE |
+ |_____________| | FIRSTNAME |
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-working"
revision="1">
+ <title>Travailler avec l'association</title>
+
+ <para>
+ R�unissons quelques personnes et quelques �v�nements dans une nouvelle
m�thode dans
+ <literal>EventManager</literal> :
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long
personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ aPerson.getEvents().add(anEvent);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ Apr�s le chargement d'une <literal>Person</literal> et
d'un <literal>Event</literal>, modifiez
+ simplement la collection en utilisant les m�thodes normales de la
collection. Comme vous
+ pouvez le voir, il n'y a pas d'appel explicite �
<literal>update()</literal> ou
+ <literal>save()</literal>, Hibernate d�tecte automatiquement
que la collection a �t�
+ modifi�e et a besoin d'�tre mise � jour. Ceci est appel�
<emphasis>la v�rification sale
+ automatique</emphasis> (NdT : "automatic dirty
checking"), et vous pouvez aussi l'essayer en
+ modifiant le nom ou la propri�t� date de n'importe lequel de vos
objets. Tant qu'ils sont dans
+ un �tat <emphasis>persistant</emphasis>, c'est-�-dire,
li�s � une <literal>Session</literal> Hibernate
+ particuli�re (c-�-d qu'ils ont juste �t� charg�s ou sauvegard�s dans
une unit� de travail),
+ Hibernate surveille les changements et ex�cute le SQL correspondant. Le
processus de
+ synchronisation de l'�tat de la m�moire avec la base de donn�es,
g�n�ralement seulement � la fin
+ d'une unit� de travail, est appel�
<emphasis>flushing</emphasis>. Dans notre code, l'unit� de travail
+ s'ach�ve par un commit (ou rollback) de la transaction avec la base
de donn�es - comme d�fini
+ par notre option <literal>thread</literal> de configuration
pour la classe <literal>CurrentSessionContext</literal>.
+ </para>
+
+ <para>
+ Vous pourriez bien s�r charger une personne et un �v�nement dans
diff�rentes unit�s de travail. Ou
+ vous modifiez un objet � l'ext�rieur d'une
<literal>Session</literal>, s'il n'est pas dans un �tat
+ persistant (s'il �tait persistant avant, nous appelons cet �tat
<emphasis>d�tach�</emphasis>).
+ Vous pouvez m�me modifier une collection lorsqu'elle est d�tach�e:
+ </para>
+
+ <programlisting><![CDATA[private void addPersonToEvent(Long
personId, Long eventId) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session
+ .createQuery("select p from Person p left join fetch p.events where p.id
= :pid")
+ .setParameter("pid", personId)
+ .uniqueResult(); // Eager fetch the collection so we can use it detached
+
+ Event anEvent = (Event) session.load(Event.class, eventId);
+
+ session.getTransaction().commit();
+
+ // End of first unit of work
+
+ aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
+
+ // Begin second unit of work
+
+ Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
+ session2.beginTransaction();
+
+ session2.update(aPerson); // Reattachment of aPerson
+
+ session2.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ L'appel � <literal>update</literal> rend un objet d�tach�
� nouveau persistant, vous pourriez
+ dire qu'il le lie � une unit� de travail, ainsi toutes les
modifications (ajout, suppression) que vous avez faites
+ pendant qu'il �tait d�tach� peuvent �tre sauvegard�es dans la base de
donn�es
+ (il se peut que vous ayez besoin de modifier quelques unes des m�thodes
pr�c�dentes
+ pour retourner cet identifiant).
+ </para>
+
+ <programlisting><![CDATA[else if
(args[0].equals("addpersontoevent")) {
+ Long eventId = mgr.createAndStoreEvent("My Event", new Date());
+ Long personId = mgr.createAndStorePerson("Foo", "Bar");
+ mgr.addPersonToEvent(personId, eventId);
+ System.out.println("Added person " + personId + " to event " +
eventId);]]></programlisting>
+
+ <para>
+ Ce n'est pas tr�s utile dans notre situation actuelle, mais c'est
un concept important
+ que vous pouvez mettre dans votre propre application.
+ Pour le moment, compl�tez cet exercice en ajoutant une nouvelle action �
la m�thode
+ principale des <literal>EventManager</literal>s et appelez la
� partir de la ligne de
+ commande. Si vous avez besoin des identifiants d'une personne et
d'un �v�nement - la
+ m�thode <literal>save()</literal> les retourne.
+ </para>
+
+ <para>
+ C'�tait un exemple d'une association entre deux classes de m�me
importance, deux entit�s.
+ Comme mentionn� plus t�t, il y a d'autres classes et d'autres
types dans un mod�le typique,
+ g�n�ralement "moins importants". Vous en avez d�j� vu certains,
comme un <literal>int</literal>
+ ou une <literal>String</literal>. Nous appelons ces classes
des <emphasis>types de valeur</emphasis>,
+ et leurs instances <emphasis>d�pendent</emphasis> d'une
entit� particuli�re. Des instances de ces
+ types n'ont pas leur propre identit�, elles ne sont pas non plus
partag�es entre des entit�s (deux
+ personnes ne r�f�rencent pas le m�me objet
<literal>firstname</literal>, m�me si elles ont le
+ m�me pr�nom). Bien s�r, des types de valeur ne peuvent pas seulement �tre
trouv�s dans
+ le JDK (en fait, dans une application Hibernate toutes les classes du JDK
sont consid�r�es
+ comme des types de valeur), vous pouvez aussi �crire vous-m�me des
classes d�pendantes,
+ <literal>Address</literal> ou
<literal>MonetaryAmount</literal>, par exemple.
+ </para>
+
+ <para>
+ Vous pouvez aussi concevoir une collection de types de valeur. C'est
conceptuellement tr�s
+ diff�rent d'une collection de r�f�rences vers d'autres entit�s,
mais tr�s ressemblant en Java.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-valuecollections">
+ <title>Collection de valeurs</title>
+
+ <para>
+ Nous ajoutons une collection d'objets de type de valeur �
l'entit� <literal>Person</literal>.
+ Nous voulons stocker des adresses email, donc le type que nous utilisons
est <literal>String</literal>,
+ et la collection est encore un <literal>Set</literal> :
+ </para>
+ <programlisting><![CDATA[private Set emailAddresses = new
HashSet();
+
+public Set getEmailAddresses() {
+ return emailAddresses;
+}
+
+public void setEmailAddresses(Set emailAddresses) {
+ this.emailAddresses = emailAddresses;
+}]]></programlisting>
+
+ <para>
+ Le mapping de ce <literal>Set</literal> :
+ </para>
+
+ <programlisting><![CDATA[<set name="emailAddresses"
table="PERSON_EMAIL_ADDR">
+ <key column="PERSON_ID"/>
+ <element type="string" column="EMAIL_ADDR"/>
+</set>]]></programlisting>
+
+ <para>
+ La diff�rence compar�e au mapping vu plus t�t est la partie
<literal>element</literal>,
+ laquelle dit � Hibernate que la collection ne contient pas de r�f�rences
vers une autre entit�,
+ mais une collection d'�l�ments de type
<literal>String</literal> (le nom en minuscule vous
+ indique que c'est un type/convertisseur du mapping Hibernate). Une
fois encore, l'attribut
+ <literal>table</literal> de l'�l�ment
<literal>set</literal> d�termine le nom de la table pour la
+ collection. L'�l�ment <literal>key</literal> d�finit le
nom de la colonne de la clef �trang�re
+ dans la table de la collection. L'attribut
<literal>column</literal> dans l'�l�ment
+ <literal>element</literal> d�finit le nom de la colonne o�
les valeurs de <literal>String</literal>
+ seront r�ellement stock�es.
+ </para>
+
+ <para>
+ Regardons le sch�ma mis � jour :
+ </para>
+
+ <programlisting><![CDATA[
+ _____________ __________________
+ | | | | _____________
+ | EVENTS | | PERSON_EVENT | | |
___________________
+ |_____________| |__________________| | PERSON | |
|
+ | | | | |_____________| | PERSON_EMAIL_ADDR
|
+ | *EVENT_ID | <--> | *EVENT_ID | | |
|___________________|
+ | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | <--> |
*PERSON_ID |
+ | TITLE | |__________________| | AGE | | *EMAIL_ADDR
|
+ |_____________| | FIRSTNAME |
|___________________|
+ | LASTNAME |
+ |_____________|
+ ]]></programlisting>
+
+ <para>
+ Vous pouvez voir que la clef primaire de la table de la collection est en
fait une
+ clef compos�e, utilisant deux colonnes. Ceci implique aussi qu'il ne
peut pas y avoir
+ d'adresses email dupliqu�es par personne, ce qui est exactement la
s�mantique dont
+ nous avons besoin pour un ensemble en Java.
+ </para>
+
+ <para>
+ Vous pouvez maintenant tester et ajouter des �l�ments � cette collection,
juste comme
+ nous l'avons fait avant en liant des personnes et des �v�nements.
C'est le m�me code
+ en Java.
+ </para>
+
+ <programlisting><![CDATA[private void
addEmailToPerson(Long personId, String emailAddress) {
+
+ Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+ session.beginTransaction();
+
+ Person aPerson = (Person) session.load(Person.class, personId);
+
+ // The getEmailAddresses() might trigger a lazy load of the collection
+ aPerson.getEmailAddresses().add(emailAddress);
+
+ session.getTransaction().commit();
+}]]></programlisting>
+
+ <para>
+ Cette fois ci, nous n'avons pas utilis� une requ�te de chargement
agressif (<emphasis>fetch</emphasis>)
+ pour initialiser la collection. Par cons�quent, l'invocation du
getter d�clenchera un
+ select suppl�mentaire pour l'initialiser. Traquez les logs SQL et
tentez d'optimiser
+ ce cas avec un chargement aggressif.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-bidirectional"
revision="1">
+ <title>Associations bidirectionnelles</title>
+
+ <para>
+ Ensuite nous allons mapper une association bidirectionnelle - faire
fonctionner
+ l'association entre une personne et un �v�nement � partir des deux
c�t�s en Java.
+ Bien s�r, le sch�ma de la base de donn�es ne change pas, nous avons
toujours une pluralit�
+ many-to-many. Une base de donn�es relationnelle est plus flexible
qu'un langage de
+ programmation r�seau, donc elle n'a pas besoin de direction de
navigation - les donn�es
+ peuvent �tre vues et r�cup�r�es de toutes les mani�res possibles.
+ </para>
+
+ <para>
+ D'abord, ajouter une collection de participants � la classe
<literal>Event</literal> :
+ </para>
+
+ <programlisting><![CDATA[private Set participants = new HashSet();
+
+public Set getParticipants() {
+ return participants;
+}
+
+public void setParticipants(Set participants) {
+ this.participants = participants;
+}]]></programlisting>
+
+ <para>
+ Maintenant mapper ce c�t� de l'association aussi, dans
<literal>Event.hbm.xml</literal>.
+ </para>
+
+ <programlisting><![CDATA[<set name="participants"
table="PERSON_EVENT" inverse="true">
+ <key column="EVENT_ID"/>
+ <many-to-many column="PERSON_ID" class="events.Person"/>
+</set>]]></programlisting>
+
+ <para>
+ Comme vous le voyez, ce sont des mappings de
<literal>set</literal>s normaux dans les
+ deux documents de mapping. Notez que les noms de colonne dans
<literal>key</literal> et
+ <literal>many-to-many</literal> sont invers�s dans les 2
documents de mapping. L'ajout
+ le plus important ici est l'attribut
<literal>inverse="true"</literal> dans l'�l�ment
+ <literal>set</literal> du mapping de la collection des
<literal>Event</literal>s.
+ </para>
+
+ <para>
+ Ce que signifie qu'Hibernate devrait prendre l'autre c�t� - la
classe <literal>Person</literal> -
+ s'il a besoin de renseigner des informations � propos du lien entre
les deux. Ce sera
+ beaucoup plus facile � comprendre une fois que vous verrez comment le
lien bidirectionnel
+ entre les deux entit�s est cr��.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-associations-usingbidir">
+ <title>Travailler avec des liens bidirectionnels</title>
+
+ <para>
+ Premi�rement, gardez � l'esprit qu'Hibernate n'affecte pas la
s�mantique normale de Java.
+ Comment avons-nous cr�� un lien entre une
<literal>Person</literal> et un <literal>Event</literal>
+ dans l'exemple unidirectionnel ? Nous avons ajout� une instance de
<literal>Event</literal>
+ � la collection des r�f�rences d'�v�nement d'une instance de
<literal>Person</literal>. Donc,
+ �videmment, si vous voulons rendre ce lien bidirectionnel, nous devons
faire la m�me chose de
+ l'autre c�t� - ajouter une r�f�rence de
<literal>Person</literal> � la collection d'un
+ <literal>Event</literal>. Cette "configuration du lien
des deux c�t�s" est absolument
+ n�cessaire et vous ne devriez jamais oublier de le faire.
+ </para>
+
+ <para>
+ Beaucoup de d�veloppeurs programment de mani�re d�fensive et cr�ent des
+ m�thodes de gestion de lien pour affecter correctement les deux c�t�s,
+ par exemple dans <literal>Person</literal> :
+ </para>
+
+ <programlisting><![CDATA[protected Set getEvents() {
+ return events;
+}
+
+protected void setEvents(Set events) {
+ this.events = events;
+}
+
+public void addToEvent(Event event) {
+ this.getEvents().add(event);
+ event.getParticipants().add(this);
+}
+
+public void removeFromEvent(Event event) {
+ this.getEvents().remove(event);
+ event.getParticipants().remove(this);
+}]]></programlisting>
+
+ <para>
+ Notez que les m�thodes get et set pour la collection sont maintenant
prot�g�es - ceci permet � des
+ classes du m�me paquet et aux sous-classes d'acc�der encore aux
m�thodes, mais emp�che n'importe qui
+ d'autre de mettre le d�sordre directement dans les collections
(enfin, presque). Vous devriez
+ probablement faire de m�me avec la collection de l'autre c�t�.
+ </para>
+
+ <para>
+ Et � propos de l'attribut de mapping
<literal>inverse</literal> ? Pour vous, et pour Java, un lien
+ bidirectionnel est simplement une mani�re de configurer correctement les
r�f�rences des deux c�t�s.
+ Hibernate n'a cependant pas assez d'informations pour ordonner
correctement les expressions SQL
+ <literal>INSERT</literal> et
<literal>UPDATE</literal> (pour �viter les violations de contrainte), et
+ a besoin d'aide pour g�rer proprement les associations
bidirectionnelles. Rendre
+ <literal>inverse</literal> un c�t� d'une assocation dit �
Hibernate de l'ignorer essentiellement, pour
+ le consid�rer comme un <emphasis>miroir</emphasis> de
l'autre c�t�. C'est tout ce qui est n�cessaire �
+ Hibernate pour d�couvrir tout des probl�mes de transformation d'un
mod�le de navigation
+ directionnelle vers un sch�ma SQL de base de donn�es. Les r�gles dont
vous devez vous souvenir sont :
+ toutes les associations bidirectionnelles ont besoin d'un c�t� marqu�
<literal>inverse</literal>.
+ Dans une association un-vers-plusieurs vous pouvez choisir n'importe
quel c�t�, il n'y a pas de
+ diff�rence.
+ </para>
+<!--
+ <para>
+ In the next section we integrate Hibernate with Tomcat and WebWork - the
<literal>EventManager</literal>
+ doesn't scale anymore with our growing application.
+ </para>
+-->
+ </sect2>
+ </sect1>
+
+ <sect1 id="tutorial-webapp">
+ <title>Part 3 - L'application web EventManager</title>
+
+ <para>
+ Une application web Hibernate utilise la
<literal>Session</literal> et <literal>Transaction</literal>
+ comme une application standalone. Cependant, quelques patterns sont utiles.
Nous allons coder une
+ <literal>EventManagerServlet</literal>. Cette servlet peut lister
tous les �v�nements stock�s dans
+ la base de donn�es, et fournir une formulaire HTML pour saisir d'autres
�v�nements.
+ </para>
+
+ <sect2 id="tutorial-webapp-servlet">
+ <title>Ecrire la servlet de base</title>
+
+ <para>
+ Cr�ons une nouvelle classe dans notre r�pertoire source, dans le package
<literal>events</literal>:
+ </para>
+
+ <programlisting><![CDATA[package events;
+
+// Imports
+
+public class EventManagerServlet extends HttpServlet {
+
+ private final SimpleDateFormat dateFormatter =
+ new SimpleDateFormat("dd.MM.yyyy");
+
+ // Servlet code
+}]]></programlisting>
+
+ <para>
+ Le <literal>dateFormatter</literal> est un outil que nous
utiliserons plus tard pour convertir les objets
+ <literal>Date</literal> depuis et vers des chaines de
caract�res. Il est propice de n'avoir qu'un
+ formatter comme membre de la servlet.
+ </para>
+
+ <para>
+ La servlet n'accepte que les requ�tes HTTP
<literal>GET</literal>, la m�thode � impl�menter est donc
+ <literal>doGet()</literal>:
+ </para>
+
+ <programlisting><![CDATA[protected void doGet(HttpServletRequest
request,
+ HttpServletResponse response)
+ throws ServletException, IOException {
+
+ try {
+ // Begin unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().beginTransaction();
+
+ // Process request and render page...
+
+ // End unit of work
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().commit();
+
+ } catch (Exception ex) {
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().getTransaction().rollback();
+ throw new ServletException(ex);
+ }
+
+}]]></programlisting>
+
+ <para>
+ La pattern que nous utilisons ici est appel�
<emphasis>session-per-request</emphasis>.
+ Lorsqu'une requ�te touche la servlet, une nouvelle
<literal>Session</literal> hibernate est
+ ouverte � l'invocationde
<literal>getCurrentSession()</literal> sur la
+ <literal>SessionFactory</literal>. Ensuite, une transaction
avec la base de donn�es est d�marr�e—
+ tous les acc�s � la base de donn�es interviennent au sein de la
transactiton, peu importe que les donn�es
+ soient lues ou �crites (nous n'utilisons pas le mode auto-commit dans
les applications).
+ </para>
+
+ <para>
+ Ensuite, les actions possibles de la requ�tes sont ex�cut�es et la
r�ponse HTML
+ est rendue. Nous en parlerons plus tard.
+ </para>
+
+ <para>
+ Enfin, l'unit� de travail s'ach�ve lorsque l'ex�cution et le
rendu sont achev�s.
+ Si un probl�me survient lors de ces deux phases, une exception est
soulev�e et la
+ transaction avec la base de donn�es subit un rollback. Voila pour le
pattern
+ <literal>session-per-request</literal>. Au lieu d'un code
de d�marcation de transaction
+ au sein de chaque servlet, vous pouvez �crire un filtre de servlet.
+ Voir le site Hibernate et le Wiki pour plus d'information sur ce
pattern, appel�
+ <emphasis>Open Session in View</emphasis>— vous en aurez besoin
d�s que vous
+ utiliserez des JSPs et non plus des servlets pour le rendu de vos vues.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-processing">
+ <title>Proc�der et rendre</title>
+
+ <para>
+ Impl�mentons l'ex�cution de la requ�te et le rendu de la page.
+ </para>
+
+<programlisting><![CDATA[// Write HTML header
+PrintWriter out = response.getWriter();
+out.println("<html><head><title>Event
Manager</title></head><body>");
+
+// Handle actions
+if ( "store".equals(request.getParameter("action")) ) {
+
+ String eventTitle = request.getParameter("eventTitle");
+ String eventDate = request.getParameter("eventDate");
+
+ if ( "".equals(eventTitle) || "".equals(eventDate) ) {
+ out.println("<b><i>Please enter event title and
date.</i></b>");
+ } else {
+ createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate));
+ out.println("<b><i>Added event.</i></b>");
+ }
+}
+
+// Print page
+printEventForm(out);
+listEvents(out);
+
+// Write HTML footer
+out.println("</body></html>");
+out.flush();
+out.close();]]></programlisting>
+
+ <para>
+ Ce style de code avec un mix de Java et d'HTML ne serait pas scalable
+ dans une application plus complexe—gardez � l'esprit que
nous ne faisons qu'illustrer
+ les concepts basiques d'Hibernate dans ce tutoriel. Ce code affiche
une en t�te et un pied de page
+ HTML. Dans cette page, sont affich�s un formulaire pour la saisie
d'�v�nements ainsi
+ qu'une liste de tous les �v�nements de la base de donn�es. La
premi�re m�thode
+ est triviale est ne fait que sortir de l'HTML:
+ </para>
+
+ <programlisting><![CDATA[private void printEventForm(PrintWriter
out) {
+ out.println("<h2>Add new event:</h2>");
+ out.println("<form>");
+ out.println("Title: <input name='eventTitle'
length='50'/><br/>");
+ out.println("Date (e.g. 24.12.2009): <input name='eventDate'
length='10'/><br/>");
+ out.println("<input type='submit' name='action'
value='store'/>");
+ out.println("</form>");
+}]]></programlisting>
+
+ <para>
+ La m�thode <literal>listEvents()</literal> utilise la
+ <literal>Session</literal> Hibernate li�e au thread courant
pour ex�cuter la
+ requ�te:
+ </para>
+
+ <programlisting><![CDATA[private void listEvents(PrintWriter out) {
+ List result = HibernateUtil.getSessionFactory()
+ .getCurrentSession().createCriteria(Event.class).list();
+ if (result.size() > 0) {
+ out.println("<h2>Events in database:</h2>");
+ out.println("<table border='1'>");
+ out.println("<tr>");
+ out.println("<th>Event title</th>");
+ out.println("<th>Event date</th>");
+ out.println("</tr>");
+ for (Iterator it = result.iterator(); it.hasNext();) {
+ Event event = (Event) it.next();
+ out.println("<tr>");
+ out.println("<td>" + event.getTitle() +
"</td>");
+ out.println("<td>" + dateFormatter.format(event.getDate()) +
"</td>");
+ out.println("</tr>");
+ }
+ out.println("</table>");
+ }
+}]]></programlisting>
+
+ <para>
+ FEnfin, l'action <literal>store</literal> renvoie � la
m�thode
+ <literal>createAndStoreEvent()</literal>, qui utilise aussi
la
+ <literal>Session</literal> du thread courant:
+ </para>
+
+ <programlisting><![CDATA[protected void createAndStoreEvent(String
title, Date theDate) {
+ Event theEvent = new Event();
+ theEvent.setTitle(title);
+ theEvent.setDate(theDate);
+
+ HibernateUtil.getSessionFactory()
+ .getCurrentSession().save(theEvent);
+}]]></programlisting>
+
+ <para>
+ La servlet est faite. Une requ�te � la servlet sera ex�cut�e par une
seule
+ <literal>Session</literal> et
<literal>Transaction</literal>. Comme pour une application
+ standalone, Hibernate peut automatiquement lier ces objets au thread
courant d'ex�cution.
+ Cela vous laisse la libert� de s�parer votre code en couches et
d'acc�der � la
+ <literal>SessionFactory</literal> par le moyen que vous voulez.
+ G�n�ralement, vous utiliserez des conceptions plus sophistiqu�es et d�placerez
+ le code d'acc�s aux donn�es dans une couche DAO. Voir le wiki Hibernate pour
plus
+ d'exemples.
+ </para>
+
+ </sect2>
+
+ <sect2 id="tutorial-webapp-deploy">
+ <title>D�ployer et tester</title>
+
+ <para>
+ Pour d�ployer cette application, vous devez cr�er une archive Web, un
War. Ajoutez
+ la cible Ant suivante dans votre
<literal>build.xml</literal>:
+ </para>
+
+<programlisting><![CDATA[<target name="war"
depends="compile">
+ <war destfile="hibernate-tutorial.war" webxml="web.xml">
+ <lib dir="${librarydir}">
+ <exclude name="servlet.jar"/>
+ </lib>
+
+ <classes dir="${targetdir}"/>
+ </war>
+</target>]]></programlisting>
+
+ <para>
+ Cette cible cr�� un fichier nomm�
<literal>hibernate-tutorial.war</literal>
+ dans le r�pertoire de votre projet. Elle package les biblioth�ques et le
descripteur <literal>web.xml</literal>
+ qui est attendu dans le r�pertoire racine de votre projet:
+ </para>
+
+ <programlisting><![CDATA[<?xml version="1.0"
encoding="UTF-8"?>
+<web-app version="2.4"
+
xmlns="http://java.sun.com/xml/ns/j2ee"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+ <servlet>
+ <servlet-name>Event Manager</servlet-name>
+ <servlet-class>events.EventManagerServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>Event Manager</servlet-name>
+ <url-pattern>/eventmanager</url-pattern>
+ </servlet-mapping>
+</web-app>]]></programlisting>
+
+ <para>
+ Avant de compiler et d�ployer l'application web, notez qu'une
biblioth�que suppl�mentaire
+ est requise: <literal>servlet.jar</literal>. C'est le kit
de d�veloppement de Servlet Java,
+ si vous ne disposez pas de cette biblioth�que, prenez la sur le
+ <ulink
url="http://java.sun.com/products/servlet/archive.html">site de
Sun</ulink> et copiez la
+ dans votre r�pertoire des biblioth�ques. Cependant, elle ne sera utilis�e
uniquement pour la
+ compilation et sera exclue du paackage WAR.
+ </para>
+
+ <para>
+ Pour construire et d�ployer, appelez <literal>ant
war</literal> dans votre projet et
+ copier le fichier <literal>hibernate-tutorial.war</literal>
dans le r�pertoire <literal>webapp</literal> de tomcat
+ Si vous n'avez pas install� Tomcat, t�l�chargez le et suivez la
notice d'installation.
+ Vous n'avez pas � modifier la configuration Tomcat pour d�ployer
cette application.
+ </para>
+
+ <para>
+ Une fois l'application d�ploy�e et Tomcat lanc�, acc�dez �
l'application via
+
<literal>http://localhost:8080/hibernate-tutorial/eventmanager</literal>.
+ Assurez vous de consulter les traces tomcat pour observer
l'initialisation
+ d'Hibernate � la premi�re requ�te touchant votre servlet
(l'initialisation statique dans <literal>HibernateUtil</literal>
+ est invoqu�e) et pour v�rifier qu'aucune exception ne survienne.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="tutorial-summary" revision="1">
+ <title>R�sum�</title>
+
+ <para>
+ Ce didacticiel a couvert les bases de l'�criture d'une simple
application Hibernate ainsi qu'une petite application web.
+ </para>
+
+ <para>
+ Si vous �tes d�j� confiants avec Hibernate, continuez � parcourir les sujets
que vous trouvez
+ int�ressants � travers la table des mati�res de la documentation de r�f�rence
- les plus
+ demand�s sont le traitement transactionnel (<xref
linkend="transactions"/>), la performance
+ des r�cup�rations d'information (<xref
linkend="performance"/>), ou l'utilisation de l'API
+ (<xref linkend="objectstate"/>) et les fonctionnalit�s des
requ�tes (<xref linkend="objectstate-querying"/>).
+ </para>
+
+ <para>
+ N'oubliez pas de v�rifier le site web d'Hibernate pour d'autres
didacticiels (plus sp�cialis�s).
+ </para>
+
+ </sect1>
+
+</chapter>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/content/xml.xml (from rev
14070, core/trunk/documentation/manual/fr-FR/src/main/docbook/modules/xml.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/content/xml.xml
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/content/xml.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="xml">
+ <title>Mapping XML</title>
+
+ <para><emphasis>
+ Notez que cette fonctionnalit� est exp�rimentale dans Hibernate 3.0 et
+ est en d�veloppement extr�mement actif.
+ </emphasis></para>
+
+ <sect1 id="xml-intro" revision="1">
+ <title>Travailler avec des donn�es XML</title>
+
+ <para>
+ Hibernate vous laisse travailler avec des donn�es XML persistantes de la
+ m�me mani�re que vous travaillez avec des POJOs persistants. Un arbre XML
+ peut �tre vu comme une autre mani�re de repr�senter les donn�es
relationnelles
+ au niveau objet, � la place des POJOs.
+ </para>
+
+ <para>
+ Hibernate supporte dom4j en tant qu'API pour la manipulation des arbres
XML.
+ Vous pouvez �crire des requ�tes qui r�cup�rent des arbres dom4j � partie de
la
+ base de donn�es, et avoir toutes les modifications que vous faites sur
l'arbre
+ automatiquement synchronis�es dans la base de donn�es. Vous pouvez m�me
prendre
+ un document XML, l'analyser en utilisant dom4j, et l'�crire dans la
base de
+ donn�es via les op�rations basiques d'Hibernate :
+ <literal>persist(), saveOrUpdate(), merge(), delete(),
replicate()</literal>
+ (merge() n'est pas encore support�).
+ </para>
+
+ <para>
+ Cette fonctionnalit� a plusieurs applications dont l'import/export de
donn�es,
+ l'externalisation d'entit�s via JMS ou SOAP et les rapports XSLT.
+ </para>
+
+ <para>
+ Un simple mapping peut �tre utilis� pour simultan�ment mapper les propri�t�s
+ d'une classe et les noeuds d'un document XML vers la base de donn�es,
ou,
+ si il n'y a pas de classe � mapper, il peut �tre utilis� juste pour
mapper
+ le XML.
+ </para>
+
+ <sect2 id="xml-intro-mapping">
+ <title>Sp�cifier le mapping XML et le mapping d'une classe
ensemble</title>
+
+ <para>
+ Voici un exemple de mapping d'un POJO et du XML simultan�ment :
+ </para>
+
+ <programlisting><![CDATA[<class name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="accountId"
+ column="ACCOUNT_ID"
+ node="@id"/>
+
+ <many-to-one name="customer"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"/>
+
+ ...
+
+</class>]]></programlisting>
+ </sect2>
+
+ <sect2 id="xml-onlyxml">
+ <title>Sp�cifier seulement un mapping XML</title>
+
+ <para>
+ Voici un exemple dans lequel il n'y a pas de class POJO :
+ </para>
+
+ <programlisting><![CDATA[<class entity-name="Account"
+ table="ACCOUNTS"
+ node="account">
+
+ <id name="id"
+ column="ACCOUNT_ID"
+ node="@id"
+ type="string"/>
+
+ <many-to-one name="customerId"
+ column="CUSTOMER_ID"
+ node="customer/@id"
+ embed-xml="false"
+ entity-name="Customer"/>
+
+ <property name="balance"
+ column="BALANCE"
+ node="balance"
+ type="big_decimal"/>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ Ce mapping vous permet d'acc�der aux donn�es comme un arbre dom4j, ou
comme
+ un graphe de paire nom de propri�t�/valeur
(<literal>Map</literal>s java). Les
+ noms des propri�t�s sont des constructions purement logiques qui peuvent
�tre
+ r�f�r�es des dans requ�tes HQL.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="xml-mapping" revision="1">
+ <title>M�tadonn�es du mapping XML</title>
+
+ <para>
+ Plusieurs �l�ments du mapping Hibernate acceptent l'attribut
<literal>node</literal>.
+ Ceci vous permet de sp�cifier le nom d'un attribut XML ou d'un
�l�ment qui
+ contient la propri�t� ou les donn�es de l'entit�. Le format de
l'attribut
+ <literal>node</literal> doit �tre un des suivants :
+ </para>
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para><literal>"element-name"</literal> - mappe
vers l'�l�ment XML nomm�</para>
+ </listitem>
+ <listitem>
+ <para><literal>"@attribute-name"</literal> -
mappe vers l'attribut XML nomm�</para>
+ </listitem>
+ <listitem>
+ <para><literal>"."</literal> - mappe vers le
parent de l'�l�ment</para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>"element-name/@attribute-name"</literal>
-
+ mappe vers l'�l�ment nomm� de l'attribut nomm�
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Pour des collections et de simples associations valu�es, il y a un attribut
+ <literal>embed-xml</literal> suppl�mentaire. Si
<literal>embed-xml="true"</literal>,
+ qui est la valeur par d�faut, l'arbre XML pour l'entit� associ�e (ou
la collection
+ des types de valeurs) sera embarqu�e directement dans l'arbre XML pour
l'entit� qui
+ poss�de l'association. Sinon, si
<literal>embed-xml="false"</literal>, alors
+ seule la valeur de l'identifiant r�f�renc� appara�tra dans le XML pour de
simples
+ associations de points, et les collections n'appra�tront simplement pas.
+ </para>
+
+ <para>
+ Vous devriez faire attention � ne pas laisser
<literal>embed-xml="true"</literal>
+ pour trop d'associations, puisque XML ne traite pas bien les liens
circurlaires.
+ </para>
+
+ <programlisting><![CDATA[<class name="Customer"
+ table="CUSTOMER"
+ node="customer">
+
+ <id name="id"
+ column="CUST_ID"
+ node="@id"/>
+
+ <map name="accounts"
+ node="."
+ embed-xml="true">
+ <key column="CUSTOMER_ID"
+ not-null="true"/>
+ <map-key column="SHORT_DESC"
+ node="@short-desc"
+ type="string"/>
+ <one-to-many entity-name="Account"
+ embed-xml="false"
+ node="account"/>
+ </map>
+
+ <component name="name"
+ node="name">
+ <property name="firstName"
+ node="first-name"/>
+ <property name="initial"
+ node="initial"/>
+ <property name="lastName"
+ node="last-name"/>
+ </component>
+
+ ...
+
+</class>]]></programlisting>
+
+ <para>
+ dans ce cas, nous avons d�cid� d'embarquer la collection
d'identifiants de compte,
+ mais pas les donn�es actuelles du compte. La requ�te HQL suivante :
+ </para>
+
+ <programlisting><![CDATA[from Customer c left join fetch c.accounts
where c.lastName like :lastName]]></programlisting>
+
+ <para>
+ devrait retourner l'ensemble de donn�es suivant :
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account short-desc="Savings">987632567</account>
+ <account short-desc="Credit Card">985612323</account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ <para>
+ Si vous positionnez <literal>embed-xml="true"</literal>
sur le mapping
+ <literal><one-to-many></literal>, les donn�es
pourraient
+ ressembler plus � �a :
+ </para>
+
+ <programlisting><![CDATA[<customer id="123456789">
+ <account id="987632567" short-desc="Savings">
+ <customer id="123456789"/>
+ <balance>100.29</balance>
+ </account>
+ <account id="985612323" short-desc="Credit Card">
+ <customer id="123456789"/>
+ <balance>-2370.34</balance>
+ </account>
+ <name>
+ <first-name>Gavin</first-name>
+ <initial>A</initial>
+ <last-name>King</last-name>
+ </name>
+ ...
+</customer>]]></programlisting>
+
+ </sect1>
+
+
+ <sect1 id="xml-manipulation" revision="1">
+ <title>Manipuler des donn�es XML</title>
+
+ <para>
+ Relisons et mettons � jour des documents XML dans l'application. Nous
faisons
+ �a en obtenant une session dom4j :
+ </para>
+
+ <programlisting><![CDATA[Document doc = ....;
+
+Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+List results = dom4jSession
+ .createQuery("from Customer c left join fetch c.accounts where c.lastName like
:lastName")
+ .list();
+for ( int i=0; i<results.size(); i++ ) {
+ //add the customer data to the XML document
+ Element customer = (Element) results.get(i);
+ doc.getRootElement().add(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <programlisting><![CDATA[Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+Element cust = (Element) dom4jSession.get("Customer", customerId);
+for ( int i=0; i<results.size(); i++ ) {
+ Element customer = (Element) results.get(i);
+ //change the customer name in the XML and database
+ Element name = customer.element("name");
+ name.element("first-name").setText(firstName);
+ name.element("initial").setText(initial);
+ name.element("last-name").setText(lastName);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+ <para>
+ Il est extr�mement utile de combiner cette fonctionnalit� avec
l'op�ration
+ <literal>replicate()</literal> d'Hibernate pour impl�menter
des imports/exports
+ de donn�es XML.
+ </para>
+
+ </sect1>
+
+</chapter>
+
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/AuthorWork.png
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/AuthorWork.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/AuthorWork.zargo
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/AuthorWork.zargo
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/CustomerOrderProduct.png
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/CustomerOrderProduct.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/CustomerOrderProduct.zargo
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/CustomerOrderProduct.zargo
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/EmployerEmployee.png
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/EmployerEmployee.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/EmployerEmployee.zargo
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/EmployerEmployee.zargo
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.png
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.svg
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.svg
(rev 0)
+++
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.svg 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,429 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+
xmlns="http://www.w3.org/2000/svg"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="354.331"
+ height="336.614"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g659">
+ <rect
+ width="212.257"
+ height="57.2441"
+ x="17.9576"
+ y="100.132"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ transform="matrix(0.743454,0,0,0.482981,6.46949,52.2178)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="17.4083"
+ y="15.194"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="325.86"
+ height="63.6537"
+ x="13.6713"
+ y="12.4966"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,105.325)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <text
+ x="170.824753"
+ y="58.402939"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="170.824997"
+ y="58.402901"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="178.076340"
+ y="364.281433"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="178.076004"
+ y="364.281006"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="68.605331"
+ y="138.524582"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="68.605301"
+ y="138.524994"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="196.927"
+ y="89.2389"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="67.0014"
+ height="101.35"
+ x="194.633"
+ y="86.4389"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ <text
+ x="249.108841"
+ y="173.885559"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="249.108994"
+ y="173.886002"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="270.995"
+ y="90.0018"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="73.0355"
+ height="101.35"
+ x="267.869"
+ y="87.2018"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ <text
+ x="328.593658"
+ y="174.715622"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="328.593994"
+ y="174.716003"
+ id="tspan563">
+Transaction</tspan>
+ </text>
+ <g
+ transform="matrix(0.29544,0,0,0.397877,9.70533,103.96)"
+ style="font-size:12;"
+ id="g565">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect566" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect567" />
+ </g>
+ <text
+ x="25.592752"
+ y="204.497803"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text568">
+ <tspan
+ x="25.592800"
+ y="204.498001"
+ id="tspan662">
+TransactionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.298082,0,0,0.397877,99.6898,103.96)"
+ style="font-size:12;"
+ id="g573">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect574" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect575" />
+ </g>
+ <text
+ x="134.030670"
+ y="205.532791"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text576">
+ <tspan
+ x="134.031006"
+ y="205.533005"
+ id="tspan664">
+ConnectionProvider</tspan>
+ </text>
+ <g
+ transform="matrix(1.14345,0,0,0.729078,-1.67818,38.9539)"
+ style="font-size:12;"
+ id="g587">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect588" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect589" />
+ </g>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="25.6196"
+ y="206.028"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect594" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="24.4229"
+ y="204.135"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect595" />
+ <text
+ x="85.575645"
+ y="282.300354"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text596">
+ <tspan
+ x="85.575600"
+ y="282.299988"
+ id="tspan607">
+JNDI</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="236.937"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect610" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="235.741"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect611" />
+ <text
+ x="342.093201"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text612">
+ <tspan
+ x="342.092987"
+ y="283.226013"
+ id="tspan621">
+JTA</tspan>
+ </text>
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="130.134"
+ y="206.791"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect616" />
+ <rect
+ width="90.951"
+ height="44.4829"
+ x="128.937"
+ y="204.898"
+ style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect617" />
+ <text
+ x="212.445343"
+ y="283.226410"
+ transform="scale(0.823795,0.823795)"
+
style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text618">
+ <tspan
+ x="212.445007"
+ y="283.226013"
+ id="tspan623">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,6.19341)"
+ style="font-size:12;"
+ id="g637">
+ <g
+ transform="matrix(0.499515,0,0,0.415467,-0.237339,5.61339)"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="33.749969"
+ y="50.589706"
+
style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="33.750000"
+ y="50.589699"
+ id="tspan635">
+Transient Objects</tspan>
+ </text>
+ </g>
+ <g
+ transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+ style="font-size:12;"
+ id="g644">
+ <g
+ transform="matrix(0.297486,0,0,0.516482,230.251,36.9178)"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="277.123230"
+ y="85.155571"
+
style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="277.122986"
+ y="85.155602"
+ id="tspan631">
+Persistent</tspan>
+ <tspan
+ x="277.122986"
+ y="96.155602"
+ id="tspan633">
+Objects</tspan>
+ </text>
+ </g>
+</svg>
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/hibernate_logo_a.png
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/hibernate_logo_a.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.png
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.svg
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.svg
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.svg 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,334 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+
xmlns="http://www.w3.org/2000/svg"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="318.898"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="17.3169"
+ y="18.646"
+ style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="291.837"
+ height="57.0074"
+ x="13.9703"
+ y="16.2302"
+ style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ <g
+ transform="matrix(0.326107,0,0,0.765831,9.59261,8.98517)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(1.02406,0,0,0.652953,0.223384,39.9254)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.449834,0,0,0.338463,-3.15909,9.73319)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="302.277679"
+ y="65.943230"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="302.277954"
+ y="65.943184"
+ id="tspan360">
+Application</tspan>
+ </text>
+ <text
+ x="36.235924"
+ y="63.796055"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="36.235950"
+ y="63.796051"
+ id="tspan427">
+Transient Objects</tspan>
+ </text>
+ <text
+ x="180.416245"
+ y="290.543701"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="180.415939"
+ y="290.543549"
+ id="tspan421">
+Database</tspan>
+ </text>
+ <text
+ x="25.037701"
+ y="179.154755"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="25.037655"
+ y="179.154648"
+ id="tspan384">
+SessionFactory</tspan>
+ </text>
+ <g
+ transform="matrix(0.252763,0,0,0.765831,109.104,8.98517)"
+ style="font-size:12;"
+ id="g386">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect387" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect388" />
+ </g>
+ <g
+ transform="matrix(0.297394,0,0,0.572692,101.502,21.6359)"
+ style="font-size:12;"
+ id="g364">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect365" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect366" />
+ </g>
+ <text
+ x="202.746506"
+ y="102.992203"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+ id="text367">
+ <tspan
+ x="202.746948"
+ y="102.992249"
+ id="tspan423">
+Persistent</tspan>
+ <tspan
+ x="202.746948"
+ y="116.992355"
+ id="tspan425">
+Objects</tspan>
+ </text>
+ <text
+ x="174.458496"
+ y="180.080795"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text389">
+ <tspan
+ x="174.458618"
+ y="180.080338"
+ id="tspan392">
+Session</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,188.675,8.98517)"
+ style="font-size:12;"
+ id="g394">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect395" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect396" />
+ </g>
+ <text
+ x="260.413269"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text397">
+ <tspan
+ x="260.412964"
+ y="179.154343"
+ id="tspan400">
+JDBC</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,229.156,8.98517)"
+ style="font-size:12;"
+ id="g405">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect406" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect407" />
+ </g>
+ <text
+ x="320.606903"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text408">
+ <tspan
+ x="320.606964"
+ y="179.154343"
+ id="tspan417">
+JNDI</tspan>
+ </text>
+ <g
+ transform="matrix(0.127369,0,0,0.765831,269.281,8.98517)"
+ style="font-size:12;"
+ id="g411">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect412" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect413" />
+ </g>
+ <text
+ x="377.096313"
+ y="179.154739"
+ transform="scale(0.73778,0.73778)"
+
style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text414">
+ <tspan
+ x="377.096008"
+ y="179.154999"
+ id="tspan145">
+JTA</tspan>
+ </text>
+</svg>
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.png
===================================================================
(Binary files differ)
Property changes on:
core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.svg
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.svg
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.svg 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,250 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+
xmlns="http://www.w3.org/2000/svg"
+
xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="248.031"
+ height="248.031"
+ id="svg1">
+ <defs
+ id="defs3">
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop128" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop129" />
+ </linearGradient>
+ <linearGradient
+ x1="0"
+ y1="0"
+ x2="1"
+ y2="0"
+ id="linearGradient130"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ <radialGradient
+ cx="0.5"
+ cy="0.5"
+ fx="0.5"
+ fy="0.5"
+ r="0.5"
+ id="radialGradient131"
+ xlink:href="#linearGradient127"
+ gradientUnits="objectBoundingBox"
+ spreadMethod="pad" />
+ </defs>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,-3.02123)"
+ style="font-size:12;"
+ id="g158">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="17.3527"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect136" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="15.3883"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect126" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,3.04452)"
+ style="font-size:12;"
+ id="g161">
+ <rect
+ width="285.502"
+ height="118.523"
+ x="16.6979"
+ y="99.2053"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect137" />
+ <rect
+ width="285.502"
+ height="118.523"
+ x="13.4238"
+ y="95.9309"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect132" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,4.36019,8.0993)"
+ style="font-size:12;"
+ id="g164">
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="16.6979"
+ y="222.966"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect138" />
+ <rect
+ width="285.502"
+ height="77.2688"
+ x="14.7335"
+ y="221.002"
+ transform="translate(-1.30962,-1.30992)"
+ style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect133" />
+ </g>
+ <g
+ transform="matrix(0.771934,0,0,0.543505,2.59104,21.1103)"
+ style="font-size:12;"
+ id="g167">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect134" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect135" />
+ </g>
+ <text
+ x="105.392174"
+ y="56.568123"
+ transform="scale(0.771934,0.771934)"
+
style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text183">
+ <tspan
+ x="105.392273"
+ y="56.568146"
+ id="tspan186">
+Application</tspan>
+ </text>
+ <text
+ x="81.820183"
+ y="103.149330"
+ transform="scale(0.771934,0.771934)"
+
style="font-size:20;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text188">
+ <tspan
+ x="81.820213"
+ y="103.149727"
+ id="tspan206">
+Persistent Objects</tspan>
+ </text>
+ <text
+ x="111.548180"
+ y="278.927887"
+ transform="scale(0.771934,0.771934)"
+
style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text197">
+ <tspan
+ x="111.547874"
+ y="278.927551"
+ id="tspan200">
+Database</tspan>
+ </text>
+ <text
+ x="94.436180"
+ y="153.805740"
+ transform="scale(0.771934,0.771934)"
+
style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+ id="text216">
+ <tspan
+ x="94.436180"
+ y="153.805740"
+ id="tspan221">
+HIBERNATE</tspan>
+ </text>
+ <g
+ transform="matrix(0.771934,0,0,0.771934,2.59083,1.02261)"
+ style="font-size:12;"
+ id="g254">
+ <g
+ transform="translate(4.58374,2.61928)"
+ id="g176">
+ <g
+ transform="matrix(0.571429,0,0,0.67347,-10.6174,117.093)"
+ id="g170">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect171" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect172" />
+ </g>
+ <g
+ transform="matrix(0.571429,0,0,0.67347,138.682,117.093)"
+ id="g173">
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="61.8805"
+ y="68.4288"
+ style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect174" />
+ <rect
+ width="199.065"
+ height="61.5532"
+ x="59.2613"
+ y="65.8095"
+ style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+ id="rect175" />
+ </g>
+ </g>
+ <text
+ x="47.259438"
+ y="182.367538"
+ style="font-weight:bold;stroke-width:1pt;font-family:Courier;"
+ id="text191">
+ <tspan
+ x="47.259399"
+ y="182.367996"
+ id="tspan212">
+hibernate.</tspan>
+ <tspan
+ x="47.259399"
+ y="194.367996"
+ id="tspan214">
+properties</tspan>
+ </text>
+ <text
+ x="198.523010"
+ y="188.260941"
+ style="font-weight:normal;stroke-width:1pt;font-family:helvetica;"
+ id="text194">
+ <tspan
+ id="tspan195">
+XML Mapping</tspan>
+ </text>
+ </g>
+</svg>
Copied: core/trunk/documentation/manual/fr-FR/src/main/docbook/legal_notice.xml (from rev
14073, core/trunk/documentation/manual/en-US/src/main/docbook/legal_notice.xml)
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/legal_notice.xml
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/legal_notice.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,52 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<!--
+ ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ ~
+ ~ 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, v. 2.1. This program is distributed in the
+ ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ ~ distribution; if not, write to the Free Software Foundation, Inc.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ~
+ ~ Red Hat Author(s): Steve Ebersole
+ -->
+<legalnotice id="Legal_Notice">
+ <title>Legal Notice</title>
+ <para>
+ <address>
+ <street>1801 Varsity Drive</street>
+ <city>Raleigh</city>,
<state>NC</state><postcode>27606-2072</postcode><country>USA</country>
+ <phone>Phone: +1 919 754 3700</phone>
+ <phone>Phone: 888 733 4281</phone>
+ <fax>Fax: +1 919 754 3701</fax>
+ <pob>PO Box 13588</pob><city>Research Triangle
Park</city>,
<state>NC</state><postcode>27709</postcode><country>USA</country>
+ </address>
+ </para>
+ <para>
+ Copyright <trademark class="copyright"></trademark> 2007 by
Red Hat, Inc. This material may be distributed only subject to the terms and conditions
set forth in the Open Publication License, V1.0 or later (the latest version is presently
available at <ulink
url="http://www.opencontent.org/openpub/">http://www.opencon...>).
+ </para>
+ <para>
+ Distribution of substantively modified versions of this document is prohibited
without the explicit permission of the copyright holder.
+ </para>
+ <para>
+ Distribution of the work or derivative of the work in any standard (paper) book
form for commercial purposes is prohibited unless prior permission is obtained from the
copyright holder.
+ </para>
+ <para>
+ Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of
Red Hat, Inc. in the United States and other countries.
+ </para>
+ <para>
+ All other trademarks referenced herein are the property of their respective owners.
+ </para>
+ <para>
+ The GPG fingerprint of the security(a)redhat.com key is:
+ </para>
+ <para>
+ CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
+ </para>
+</legalnotice>
\ No newline at end of file
Deleted: core/trunk/documentation/manual/fr-FR/src/main/docbook/master.xml
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/master.xml 2007-10-09 18:14:35
UTC (rev 14073)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/master.xml 2007-10-09 18:28:36
UTC (rev 14074)
@@ -1,188 +0,0 @@
-<?xml version='1.0' encoding="iso-8859-1"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
- "../support/docbook-dtd/docbookx.dtd"
-[
-<!ENTITY tutorial SYSTEM "modules/tutorial.xml">
-<!ENTITY architecture SYSTEM "modules/architecture.xml">
-<!ENTITY configuration SYSTEM "modules/configuration.xml">
-<!ENTITY persistent-classes SYSTEM "modules/persistent_classes.xml">
-<!ENTITY basic-mapping SYSTEM "modules/basic_mapping.xml">
-<!ENTITY collection-mapping SYSTEM "modules/collection_mapping.xml">
-<!ENTITY association-mapping SYSTEM
"modules/association_mapping.xml">
-<!ENTITY component-mapping SYSTEM "modules/component_mapping.xml">
-<!ENTITY inheritance-mapping SYSTEM
"modules/inheritance_mapping.xml">
-<!ENTITY session-api SYSTEM "modules/session_api.xml">
-<!ENTITY transactions SYSTEM "modules/transactions.xml">
-<!ENTITY events SYSTEM "modules/events.xml">
-<!ENTITY batch SYSTEM "modules/batch.xml">
-<!ENTITY query-hql SYSTEM "modules/query_hql.xml">
-<!ENTITY query-criteria SYSTEM "modules/query_criteria.xml">
-<!ENTITY query-sql SYSTEM "modules/query_sql.xml">
-<!ENTITY filters SYSTEM "modules/filters.xml">
-<!ENTITY xml SYSTEM "modules/xml.xml">
-<!ENTITY performance SYSTEM "modules/performance.xml">
-<!ENTITY toolset-guide SYSTEM "modules/toolset_guide.xml">
-<!ENTITY example-parentchild SYSTEM
"modules/example_parentchild.xml">
-<!ENTITY example-weblog SYSTEM "modules/example_weblog.xml">
-<!ENTITY example-mappings SYSTEM "modules/example_mappings.xml">
-<!ENTITY best-practices SYSTEM "modules/best_practices.xml">
-]>
-
-<book lang="fr">
-
- <bookinfo>
- <title>HIBERNATE - Persistance relationnelle en Java
standard</title>
- <subtitle>Documentation de r�f�rence d'Hibernate</subtitle>
- <releaseinfo>3.3.0.beta1</releaseinfo>
- </bookinfo>
-
- <toc/>
-
- <preface id="preface" revision="2">
- <title>Pr�face</title>
- <para>
- Traducteur(s): Vincent Ricard, Sebastien Cesbron, Michael Courcy, Vincent
Gigu�re, Baptiste Mathus, Emmanuel Bernard, Anthony Patricio
- </para>
- <para>
- Travailler dans les deux univers que sont l'orient� objet et la base de
donn�es
- relationnelle peut �tre lourd et consommateur en temps dans le monde de
- l'entreprise d'aujourd'hui. Hibernate est un outil de mapping
objet/relationnel
- pour le monde Java. Le terme mapping objet/relationnel (ORM) d�crit la
technique
- consistant � faire le lien entre la repr�sentation objet des donn�es
- et sa repr�sentation relationnelle bas�e sur un sch�ma SQL.
- </para>
-
- <para>
- Non seulement, Hibernate s'occupe du transfert des classes Java dans les
tables
- de la base de donn�es (et des types de donn�es Java dans les types de donn�es
SQL),
- mais il permet de requ�ter les donn�es et propose des moyens de les
r�cup�rer.
- Il peut donc r�duire de mani�re significative le temps de d�veloppement qui
- aurait �t� autrement perdu dans une manipulation manuelle des donn�es via
SQL
- et JDBC.
- </para>
-
- <para>
- Le but d'Hibernate est de lib�rer le d�veloppeur de 95 pourcent des
t�ches de
- programmation li�es � la persistance des donn�es communes. Hibernate
n'est
- probablement pas la meilleure solution pour les applications centr�es sur
les
- donn�es qui n'utilisent que les proc�dures stock�es pour impl�menter la
logique
- m�tier dans la base de donn�es, il est le plus utile dans les mod�les m�tier
orient�s
- objets dont la logique m�tier est impl�ment�e dans la couche Java dite
interm�diaire.
- Cependant, Hibernate vous aidera � supprimer ou � encapsuler le code SQL
- sp�cifique � votre base de donn�es et vous aidera sur la t�che commune
qu'est
- la transformation des donn�es d'une repr�sentation tabulaire � une
- repr�sentation sous forme de graphe d'objets.
- </para>
-
- <para>
- Si vous �tes nouveau dans Hibernate et le mapping Objet/Relationnel voire
m�me en Java,
- suivez ces quelques �tapes :
- </para>
-
- <orderedlist>
- <listitem>
- <para>
- Lisez <xref linkend="tutorial"/> pour un didacticiel
plus long avec plus d'instructions �tape par �tape.
- </para>
- </listitem>
- <listitem>
- <para>
- Lisez <xref linkend="architecture"/> pour comprendre
les environnements dans lesquels
- Hibernate peut �tre utilis�.
- </para>
- </listitem>
- <listitem>
- <para>
- Regardez le r�pertoire <literal>eg</literal> de la
distribution Hibernate, il contient
- une application simple et autonome. Copiez votre pilote JDBC dans le
r�pertoire
- <literal>lib/</literal> et �ditez
<literal>src/hibernate.properties</literal>, en
- positionnant correctement les valeurs pour votre base de donn�es. A
partir d'une
- invite de commande dans le r�pertoire de la distribution, tapez
<literal>ant eg</literal>
- (cela utilise Ant), ou sous Windows tapez <literal>build
eg</literal>.
- </para>
- </listitem>
- <listitem>
- <para>
- Fa�tes de cette documentation de r�f�rence votre principale source
d'information.
- Pensez � lire <emphasis>Java Persistence with
Hibernate</emphasis>
- (
http://www.manning.com/bauer2) si vous avez besoin de plus
d'aide avec le design
- d'applications ou si vous pr�f�rez un tutoriel pas � pas. Visitez
aussi
-
http://caveatemptor.hibernate.org et t�l�chargez l'application
exemple
- pour Java Persistence with Hibernate.
- </para>
- </listitem>
- <listitem>
- <para>
- Les questions les plus fr�quemment pos�es (FAQs) trouvent leur
r�ponse sur le
- site web Hibernate.
- </para>
- </listitem>
- <listitem>
- <para>
- Des d�mos, exemples et tutoriaux de tierces personnes sont r�f�renc�s
sur
- le site web Hibernate.
- </para>
- </listitem>
- <listitem>
- <para>
- La zone communautaire (Community Area) du site web Hibernate est une
- bonne source d'information sur les design patterns et sur
diff�rentes
- solutions d'int�gration d'Hibernate (Tomcat, JBoss, Spring
Framework, Struts,
- EJB, etc).
- </para>
- </listitem>
- </orderedlist>
-
- <para>
- Si vous avez des questions, utilisez le forum utilisateurs du site web
Hibernate.
- Nous utilisons �galement l'outil de gestion des incidents JIRA pour tout
ce qui
- est rapports de bogue et demandes d'�volution. Si vous �tes int�ress�
par le
- d�veloppement d'Hibernate, joignez-vous � la liste de diffusion de
d�veloppement.
- </para>
-
- <para>
- Le d�veloppement commercial, le support de production et les formations �
Hibernate
- sont propos�s par JBoss Inc (voir
http://www.hibernate.org/SupportTraining/). Hibernate
- est un projet Open Source professionnel et un composant critique de la suite
de produits
- JBoss Enterprise Middleware System (JEMS).
- </para>
-
- </preface>
-
- &tutorial;
-
- &architecture;
-
- &configuration;
-
- &persistent-classes;
-
- &basic-mapping;
- &collection-mapping;
- &association-mapping;
- &component-mapping;
- &inheritance-mapping;
-
- &session-api;
- &transactions;
- &events;
- &batch;
-
- &query-hql;
- &query-criteria;
- &query-sql;
- &filters;
- &xml;
-
- &performance;
-
- &toolset-guide;
-
- &example-parentchild;
- &example-weblog;
- &example-mappings;
-
- &best-practices;
-
-</book>
-
Added: core/trunk/documentation/manual/fr-FR/src/main/docbook/translators.xml
===================================================================
--- core/trunk/documentation/manual/fr-FR/src/main/docbook/translators.xml
(rev 0)
+++ core/trunk/documentation/manual/fr-FR/src/main/docbook/translators.xml 2007-10-09
18:28:36 UTC (rev 14074)
@@ -0,0 +1,34 @@
+<?xml version='1.0'?>
+
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<authorgroup id="AuthorGroup">
+ <othercredit class="translator">
+ <firstname>Vincent</firstname>
+ <surname>Ricard</surname>
+ </othercredit>
+ <othercredit class="translator">
+ <firstname>Sebastien</firstname>
+ <surname>Cesbron</surname>
+ </othercredit>
+ <othercredit class="translator">
+ <firstname>Michael</firstname>
+ <surname>Courcy</surname>
+ </othercredit>
+ <othercredit class="translator">
+ <firstname>Vincent</firstname>
+ <surname>Giguère</surname>
+ </othercredit>
+ <othercredit class="translator">
+ <firstname>Baptiste</firstname>
+ <surname>Mathus</surname>
+ </othercredit>
+ <othercredit class="translator">
+ <firstname>Emmanuel</firstname>
+ <surname>Bernard</surname>
+ </othercredit>
+ <othercredit class="translator">
+ <firstname>Anthony</firstname>
+ <surname>Patricio</surname>
+ </othercredit>
+</authorgroup>
\ No newline at end of file