[hibernate-commits] Hibernate SVN: r14074 - in
core/trunk/documentation/manual/fr-FR/src/main: docbook and 2
other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Tue Oct 9 14:28:37 EDT 2007
Author: steve.ebersole at 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 e