[hibernate-commits] Hibernate SVN: r10540 - trunk/Hibernate3/doc/reference/fr/modules

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Oct 2 14:02:22 EDT 2006


Author: AnthonyHib
Date: 2006-10-02 14:02:18 -0400 (Mon, 02 Oct 2006)
New Revision: 10540

Modified:
   trunk/Hibernate3/doc/reference/fr/modules/batch.xml
   trunk/Hibernate3/doc/reference/fr/modules/persistent_classes.xml
   trunk/Hibernate3/doc/reference/fr/modules/query_hql.xml
   trunk/Hibernate3/doc/reference/fr/modules/tutorial.xml
Log:
update for 3.2 doc compliance

Modified: trunk/Hibernate3/doc/reference/fr/modules/batch.xml
===================================================================
--- trunk/Hibernate3/doc/reference/fr/modules/batch.xml	2006-09-30 02:49:47 UTC (rev 10539)
+++ trunk/Hibernate3/doc/reference/fr/modules/batch.xml	2006-10-02 18:02:18 UTC (rev 10540)
@@ -33,6 +33,12 @@
 
     <programlisting><![CDATA[hibernate.jdbc.batch_size 20]]></programlisting>
 
+    <para id="disablebatching" revision="1">
+        Notez qu'Hibernate désactive, de manière transparente, l'insertion par paquet au
+        niveau JDBC si vous utilisez un générateur d'identifiant de type
+        <literal>identity</literal>.
+    </para>
+
     <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é :
@@ -218,8 +224,8 @@
 session.close();]]></programlisting>
 
         <para>
-            Par défaut, les statements HQL <literal>UPDATE</literal>, n'affectent pas la valeur des propriétés 
-            <xref linkend="mapping-declaration-version">version</xref> ou 
+            Par défaut, les statements HQL <literal>UPDATE</literal>, n'affectent pas la valeur des propriétés
+            <xref linkend="mapping-declaration-version">version</xref> ou
             <xref linkend="mapping-declaration-timestamp">timestamp</xref>
             pour les entités affectées; ceci est compatible avec la spec EJB3. Toutefois,
             vous pouvez forcer Hibernate à mettre à jour les valeurs des propriétés

Modified: trunk/Hibernate3/doc/reference/fr/modules/persistent_classes.xml
===================================================================
--- trunk/Hibernate3/doc/reference/fr/modules/persistent_classes.xml	2006-09-30 02:49:47 UTC (rev 10539)
+++ trunk/Hibernate3/doc/reference/fr/modules/persistent_classes.xml	2006-10-02 18:02:18 UTC (rev 10540)
@@ -6,7 +6,7 @@
         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 
+        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>
 
@@ -116,7 +116,7 @@
             <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 
+                <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>
@@ -148,7 +148,7 @@
             <itemizedlist spacing="compact">
                 <listitem>
                     <para>
-                        Les réattachements transitifs pour les objets détachés (mise à jour en cascade ou fusion en cascade) - 
+                        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>
@@ -270,13 +270,13 @@
             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 
+            <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. 
+            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>
 
@@ -314,7 +314,7 @@
 }]]></programlisting>
 
         <para>
-            Notez qu'une clef métier ne doit pas être solide comme une clef primaire de base de données 
+            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>
@@ -461,7 +461,7 @@
 
     </sect1>
 
-    <sect1 id="persistent-classes-tuplizers" revision="0">
+    <sect1 id="persistent-classes-tuplizers" revision="1">
         <title>Tuplizers</title>
 
         <para>
@@ -473,7 +473,7 @@
             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
+            représentés 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.
@@ -509,7 +509,7 @@
 
 
 public class CustomMapTuplizerImpl
-        extends org.hibernate.tuple.DynamicMapEntityTuplizer {
+        extends org.hibernate.tuple.entity.DynamicMapEntityTuplizer {
     // override the buildInstantiator() method to plug in our custom map...
     protected final Instantiator buildInstantiator(
             org.hibernate.mapping.PersistentClass mappingInfo) {

Modified: trunk/Hibernate3/doc/reference/fr/modules/query_hql.xml
===================================================================
--- trunk/Hibernate3/doc/reference/fr/modules/query_hql.xml	2006-09-30 02:49:47 UTC (rev 10539)
+++ trunk/Hibernate3/doc/reference/fr/modules/query_hql.xml	2006-10-02 18:02:18 UTC (rev 10540)
@@ -42,8 +42,8 @@
         <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, 
+            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>
 
@@ -158,7 +158,7 @@
             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 
+            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>
 
@@ -174,15 +174,15 @@
             <literal>setFirstResult()</literal>, ces opérations étant basées sur le nombre de résultats qui contient
             généralement des doublons dès que des collections sont chargées.
             <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 
+            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) 
+            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>
 
@@ -190,7 +190,7 @@
         <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>
 
@@ -199,14 +199,14 @@
         </para>
 
         <para>
-            Les requêtes présentes dans la section précédente utilisent la forme <literal>explicite</literal> 
+            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> 
+            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>
 
@@ -399,7 +399,7 @@
         <title>La clause where</title>
 
         <para>
-            La clause <literal>where</literal> vous permet de réduire la liste des instances retournées. 
+            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>
 
@@ -615,7 +615,7 @@
             <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> 
+                    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>
@@ -823,11 +823,11 @@
         </para>
     </sect1>
 
-    <sect1 id="queryhql-grouping">
+    <sect1 id="queryhql-grouping" revision="1">
         <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 :
+            Si la requête retourne des valeurs aggrégées, celles-ci peuvent être groupées par propriété d'une classe retournée ou par composant :
         </para>
 
         <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat)
@@ -848,20 +848,24 @@
 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).
+            Les fonctions SQL et les fonctions d'agrégat sont permises dans les clauses <literal>having</literal>
+            et <literal>order by</literal>, si elles sont prises en charge 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
+group by cat.id, cat.name, cat.other, cat.properties
 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.
+            Notez aussi qu'Hibernate ne développe pas une entité faisant partie du regroupement,
+            donc vous ne pouvez pas écrire <literal>group by cat</literal> si toutes
+            les propriétés de <literal>cat</literal> sont non-agrégées. Vous devez
+            lister toutes les propriétés non-agrégées explicitement.
         </para>
 
     </sect1>
@@ -913,7 +917,7 @@
 )]]></programlisting>
 
         <para>
-            Notez que sur certaines bases de données (mais par Oracle ou HSQL), vous pouvez utiliser des constructeurs de tuples 
+            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>
 

Modified: trunk/Hibernate3/doc/reference/fr/modules/tutorial.xml
===================================================================
--- trunk/Hibernate3/doc/reference/fr/modules/tutorial.xml	2006-09-30 02:49:47 UTC (rev 10539)
+++ trunk/Hibernate3/doc/reference/fr/modules/tutorial.xml	2006-10-02 18:02:18 UTC (rev 10540)
@@ -18,7 +18,7 @@
             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>.
@@ -351,14 +351,14 @@
             </para>
 
             <para>
-                Créez un répertoire appelé <literal>data</literal> à la racine du répertoire de développement - 
+                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 données.
                 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>
@@ -533,7 +533,7 @@
 
             <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. 
+                démarrage et rend la gestion des <literal>Session</literal>s plus facile.
                 Regardons l'implémentation :
             </para>
 
@@ -614,7 +614,7 @@
 
         </sect2>
 
-        <sect2 id="tutorial-firstapp-workingpersistence" revision="4">
+        <sect2 id="tutorial-firstapp-workingpersistence" revision="5">
             <title>Charger et stocker des objets</title>
 
             <para>
@@ -655,8 +655,10 @@
         session.save(theEvent);
 
         session.getTransaction().commit();
-    }]]></programlisting>
+    }
 
+}]]></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
@@ -675,22 +677,39 @@
             <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>). 
+                <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
+                dans <literal>hibernate.cfg.xml</literal>. Par conséquent, l'unité de travail courante est liée
+                au thread Java courant qui exécute notre application. Cependant, ce n'est pas tout, vous devez
+                aussi considérer le scope, quand une unité de travail commence et quand elle finit.
+            </para>
+
+            <para>
+                Une <literal>Session</literal> commence lorsqu'elle est vraiment utilisée la première fois,
+                lorsque nous appelons <literal>getCurrentSession()</literal> pour la première fois.
+                Ensuite, elle est attachée par Hibernate au thread courant. Lorsque la transaction s'achève, par
+                commit ou par rollback, Hibernate détache automatiquement la <literal>Session</literal> du thread et la ferme
+                pour vous. Si vous invoquez <literal>getCurrentSession()</literal> une nouvelle 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.
+                Ce modèle de programmation "<emphasis>thread-bound</emphasis>" est le moyen le plus
+                populaire d'utiliser Hibernate, puisqu'il permet un découpage flexible de votre code (le code délimitant
+                les transactions peut être séparé du code accédant aux données, nous verrons cela plus loin dans ce tutorial).
             </para>
-            
+
             <para>
+                A propos du scope de l'unité de travail, la <literal>Session</literal> Hibernate devrait-elle
+                être utilisée pour exécuter une ou plusieurs opérations en base de données ? L'exemple ci-dessus
+                utilise une <literal>Session</literal> pour une opération. C'est une pure coïncidence,
+                l'exemple est n'est seulement pas assez complexe pour montrer d'autres approches. Le scope d'une
+                <literal>Session</literal> Hibernate est flexible mais vous ne devriez jamais concevoir
+                votre application de manière à utiliser une nouvelle <literal>Session</literal> Hibernate pour
+                <emphasis>chaque</emphasis> opération en base de données. Donc même si vous le voyez quelques fois
+                dans les exemples (très simplistes) suivants, considérez <emphasis>une session par operation</emphasis>
+                comme un anti-pattern. Une véritable application (web) est montrée plus loin dans ce tutorial.
+            </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>
@@ -836,7 +855,7 @@
 }]]></programlisting>
 
             <para>
-                Créez un nouveau fichier de mapping appelé <literal>Person.hbm.xml</literal> 
+                Créez un nouveau fichier de mapping appelé <literal>Person.hbm.xml</literal>
                 (n'oubliez pas la référence à la DTD)
             </para>
 
@@ -906,7 +925,7 @@
                 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>. 
+                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>
 
@@ -991,14 +1010,14 @@
                 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 
+                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>). 
+                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>
 
@@ -1037,7 +1056,7 @@
                 (il se peut que vous ayez besoin de modifier quelques unes des méthodes précédentes
                 pour retourner cet identifiant).
             </para>
-            
+
 			<para>
                 Cela n'a pas grand intérêt dans notre situation, mais c'est un concept important qu'il vous faut concevoir
                 dans votre application. Pour le moment, complétez cet excercice en ajoutant une nouvelle
@@ -1142,7 +1161,7 @@
                 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();
@@ -1284,7 +1303,7 @@
 -->
         </sect2>
     </sect1>
-    
+
     <sect1 id="tutorial-webapp">
         <title>Part 3 - L'application web EventManager</title>
 
@@ -1295,11 +1314,11 @@
             la base de données, et fournir une formulaire HTML pour saisir d'autres évènements.
         </para>
 
-        <sect2 id="tutorial-webapp-servlet" revision="1">
+        <sect2 id="tutorial-webapp-servlet" revision="2">
             <title>Ecrire la servlet de base</title>
 
             <para>
-                Créons une nouvelle classe dans notre répertoire source, dans le package <literal>events</literal>:
+                Créons une nouvelle classe dans notre répertoire source, dans le package <literal>events</literal> :
             </para>
 
             <programlisting><![CDATA[package events;
@@ -1308,29 +1327,28 @@
 
 public class EventManagerServlet extends HttpServlet {
 
-    private final SimpleDateFormat dateFormatter =
-                            new SimpleDateFormat("dd.MM.yyyy");
-
     // Servlet code
 }]]></programlisting>
 
             <para>
                 La servlet n'accepte que les requêtes HTTP <literal>GET</literal>, la méthode à implémenter est donc
-				<literal>doGet()</literal>:
+                <literal>doGet()</literal> :
             </para>
 
             <programlisting><![CDATA[protected void doGet(HttpServletRequest request,
                      HttpServletResponse response)
         throws ServletException, IOException {
 
+    SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
+
     try {
-        // Begin unit of work
+        // Début de l'unité de travail
         HibernateUtil.getSessionFactory()
                 .getCurrentSession().beginTransaction();
 
-        // Process request and render page...
+        // Traitement de la requête et rendu de la page...
 
-        // End unit of work
+        // Fin de l'unité de travail
         HibernateUtil.getSessionFactory()
                 .getCurrentSession().getTransaction().commit();
 
@@ -1343,15 +1361,22 @@
 }]]></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&mdash;
-                tous les accès à la base de données interviennent au sein de la transactiton, peu importe que les données
+                Le pattern que nous utilisons ici est appelé <emphasis>session-per-request</emphasis>.
+                Lorsqu'une requête appelle la servlet, une nouvelle <literal>Session</literal> Hibernate est
+                ouverte à l'invocation de <literal>getCurrentSession()</literal> sur la
+                <literal>SessionFactory</literal>. Ensuite, une transaction avec la base de données est démarrée &mdash;
+                tous les accès à la base de données interviennent au sein de la transaction, peu importe que les données
                 soient lues ou écrites (nous n'utilisons pas le mode auto-commit dans les applications).
             </para>
 
             <para>
+                <emphasis>N'utilisez pas</emphasis> une nouvelle <literal>Session</literal> Hibernate pour
+                chaque opération en base de données. Utilisez une <literal>Session</literal> Hibernate qui
+                porte sur l'ensemble de la requête. Utlisez <literal>getCurrentSession()</literal>,
+                ainsi elle est automatiquement attachée au thread Java courant.
+            </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>
@@ -1360,11 +1385,11 @@
                 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
+                <literal>session-per-request</literal>. Au lieu d'avoir un code de délimitant les transactions
                 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>&mdash; vous en aurez besoin dès que vous
-				utiliserez des JSPs et non plus des servlets pour le rendu de vos vues.
+                <emphasis>Open Session in View</emphasis> &mdash; vous en aurez besoin dès que vous
+                utiliserez des JSPs et non plus des servlets pour le rendu de vos vues.
             </para>
 
         </sect2>
@@ -1373,7 +1398,7 @@
             <title>Procéder et rendre</title>
 
             <para>
-                Implémentons l'exécution de la requête et le rendu de la page.                
+                Implémentons l'exécution de la requête et le rendu de la page.
             </para>
 
 <programlisting><![CDATA[// Write HTML header
@@ -1404,7 +1429,7 @@
 out.close();]]></programlisting>
 
             <para>
-                Ce style de code avec un mix de Java et d'HTML ne serait pas scalable 
+                Ce style de code avec un mix de Java et d'HTML ne serait pas scalable
                 dans une application plus complexe&mdash;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
@@ -1529,13 +1554,13 @@
             <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. 
+                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>. 
+                <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.




More information about the hibernate-commits mailing list