hibernate-orm/doc/reference/fr/modules/best_practices.xml

241 lines
14 KiB
XML
Raw Normal View History

<?xml version="1.0" encoding="iso-8859-1"?>
<chapter id="best-practices" revision="3">
<title>Meilleures pratiques</title>
<variablelist spacing="compact">
<varlistentry>
<term>D<EFBFBD>coupez finement vos classes et mappez les en utilisant <literal>&lt;component&gt;</literal>.</term>
<listitem>
<para>
Utilisez une classe <literal>Adresse</literal> pour encapsuler <literal>Rue</literal>,
<literal>Region</literal>, <literal>CodePostal</literal>.
Ceci permet la r<>utilisation du code et simplifie la maintenance.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>D<EFBFBD>clarez des propri<72>t<EFBFBD>s d'identifiants dans les classes persistantes.</term>
<listitem>
<para>
Hibernate rend les propri<72>t<EFBFBD>s d'identifiants optionnelles. Il existe beaucoup de raisons
pour lesquelles vous devriez les utiliser. Nous recommandons que vous utilisiez des identifiants
techniques (g<>n<EFBFBD>r<EFBFBD>s, et sans connotation m<>tier).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Identifiez les clefs naturelles.</term>
<listitem>
<para>
Identifiez les clefs naturelles pour toutes les entit<69>s, et mappez les avec
<literal>&lt;natural-id&gt;</literal>. Impl<70>mentez <literal>equals()</literal> et
<literal>hashCode()</literal> pour comparer les propri<72>t<EFBFBD>s qui composent la clef naturelle.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Placez chaque mapping de classe dans son propre fichier.</term>
<listitem>
<para>
N'utilisez pas un unique document de mapping. Mappez <literal>com.eg.Foo</literal> dans
le fichier <literal>com/eg/Foo.hbm.xml</literal>. Cela prend tout son sens lors
d'un travail en <20>quipe.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Chargez les mappings comme des ressources.</term>
<listitem>
<para>
D<>ployez les mappings en m<>me temps que les classes qu'ils mappent.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pensez <20> externaliser les cha<68>nes de caract<63>res.</term>
<listitem>
<para>
Ceci est une bonne habitude si vos requ<71>tes appellent des fonctions SQL qui ne sont
pas au standard ANSI. Cette externalisation dans les fichiers de mapping rendra votre
application plus portable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Utilisez les variables "bind<6E>es".</term>
<listitem>
<para>
Comme en JDBC, remplacez toujours les valeurs non constantes par "?". N'utilisez jamais
la manipulation des cha<68>nes de caract<63>res pour remplacer des valeurs non constantes dans
une requ<71>te ! Encore mieux, utilisez les param<61>tres nomm<6D>s dans les requ<71>tes.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Ne g<>rez pas vous m<>me les connexions JDBC.</term>
<listitem>
<para>
Hibernate laisse l'application g<>rer les connexions JDBC. Vous ne devriez g<>rer vos connexions
qu'en dernier recours. Si vous ne pouvez pas utiliser les syst<73>mes de connexions livr<76>s,
r<>fl<66>chissez <20> l'id<69>e de fournir votre propre impl<70>mentation de <literal>org.hibernate.connection.ConnectionProvider</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pensez <20> utiliser les types utilisateurs.</term>
<listitem>
<para>
Supposez que vous ayez une type Java, de telle biblioth<74>que, qui a besoin d'<27>tre persist<73> mais
qui ne fournit pas les accesseurs n<>cessaires pour le mapper comme composant. Vous devriez
impl<70>menter
<literal>org.hibernate.UserType</literal>.Cette approche lib<69>re le code de l'application
de l'impl<70>mentation des transformations vers / depuis les types Hibernate.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Utilisez du JDBC pur dans les goulets d'<27>tranglement.</term>
<listitem>
<para>
Dans certaines parties critiques de votre syst<73>me d'un point de vue performance, quelques op<6F>rations
peuvent tirer partie d'un appel JDBC natif.
Mais attendez de <emphasis>savoir</emphasis>
que c'est un goulet d'<27>tranglement. Ne supposez jamais qu'un appel JDBC sera forc<72>ment plus
rapide. Si vous avez besoin d'utiliser JDBC directement, ouvrez une <literal>Session</literal>
Hibernate et utilisez la connexion SQL sous-jacente. Ainsi vous pourrez utiliser la m<>me strat<61>gie
de transation et la m<>me gestion des connexions.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Comprendre le flush de <literal>Session</literal>.</term>
<listitem>
<para>
De temps en temps la Session synchronise ses <20>tats persistants avec la base de donn<6E>es.
Les performances seront affect<63>es si ce processus arrive trop souvent. Vous pouvez parfois
minimiser les flush non n<>cessaires en d<>sactivant le flush automatique ou m<>me en changeant
l'ordre des op<6F>rations men<65>es dans une transaction particuli<6C>re.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Dans une architecture <20> trois couches, pensez <20> utiliser <literal>saveOrUpdate()</literal>.</term>
<listitem>
<para>
Quand vous utilisez une architecture <20> base de servlet / session bean, vous pourriez passer
des objets charg<72>s dans le bean session vers et depuis la couche servlet / JSP. Utilisez
une nouvelle session pour traiter chaque requ<71>te.
Utilisez <literal>Session.merge()</literal> ou <literal>Session.saveOrUpdate()</literal> pour
synchroniser les objets avec la base de donn<6E>es.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Dans une architecture <20> deux couches, pensez <20> utiliser la d<>connexion de session.</term>
<listitem>
<para>
Les transactions de bases de donn<6E>es doivent <20>tre aussi courtes que possible
pour une meilleure mont<6E>e en charge.Cependant, il est souvent n<>cessaire d'impl<70>menter
de longues <emphasis>transactions applicatives</emphasis>, une simple unit<69> de travail du point de vue de
l'utilisateur. Une transaction applicative
peut s'<27>taler sur plusieurs cycles de requ<71>tes/r<>ponses du client.
Il est commun d'utiliser des objets d<>tach<63>s pour impl<70>menter des transactions applicatives.
Une alternative, extr<74>mement appropri<72>e dans une architecture <20> 2 couches, est de
maintenir un seul contact de persistance ouvert (session) pour toute la dur<75>e de vie
de la transaction applicative et simplement se d<>connecter de la connexion JDBC <20> la fin de chaque requ<71>te,
et se reconnecter au d<>but de la requ<71>te suivante. Ne partagez jamais une seule
session avec plus d'une transaction applicative, ou vous travaillerez avec des
donn<6E>es p<>rim<69>es.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Consid<EFBFBD>rez que les exceptions ne sont pas rattrapables.</term>
<listitem>
<para>
Il s'agit plus d'une pratique obligatoire que d'une "meilleure pratique". Quand une exception
intervient, il faut faire un rollback de la <literal>Transaction</literal> et
fermer la <literal>Session</literal>.
Sinon, Hibernate ne peut garantir l'int<6E>grit<69> des <20>tats persistants en m<>moire. En particulier,
n'utilisez pas <literal>Session.load()</literal> pour d<>terminer si une instance avec un identifiant
donn<6E> existe en base de donn<6E>es, utilisez <literal>Session.get()</literal> ou un requ<71>te.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pr<EFBFBD>f<EFBFBD>rez le chargement tardif des associations.</term>
<listitem>
<para>
Utilisez le chargement complet avec mod<6F>ration.
Utilisez les proxies et les collections charg<72>es tardivement
pour la plupart des associations vers des classes qui ne sont pas susceptibles
d'<27>tre compl<70>tement retenues dans le cache de second niveau.
Pour les assocations de classes en cache, o<> il y a une extr<74>mement
forte probabilit<69> que l'<27>l<EFBFBD>ment soit en cache, d<>sactivez explicitement le chargement
par jointures ouvertes en utilisant <literal>outer-join="false"</literal>.
Lorsqu'un chargement par jointure ouverte est appropri<72> pour un cas d'utilisation
particulier, utilisez une requ<71>te avec un <literal>left join fetch</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Utilisez le pattern <emphasis>d'une ouverture de session dans une vue</emphasis>,
ou une <emphasis>phase d'assemblage</emphasis> disciplin<69>e pour <20>viter des probl<62>mes
avec des donn<6E>es non rapatri<72>es.
</term>
<listitem>
<para>
Hibernate lib<69>re les d<>veloppeurs de l'<27>criture fastidieuse des <emphasis>objets de transfert
de donn<6E>es (NdT : Data Transfer Objects)</emphasis> (DTO). Dans une architecture EJB traditionnelle,
les DTOs ont deux buts : premi<6D>rement, ils contournent le probl<62>me des "entity bean" qui ne sont pas
s<>rialisables ; deuxi<78>mement, ils d<>finissent implicitement une phase d'assemblage o<> toutes les
donn<6E>es utilis<69>es par la vue sont rapatri<72>es et organis<69>es dans les DTOs avant de retourner sous le
contr<74>le de la couche de pr<70>sentation. Hibernate <20>limine le premier but. Pourtant, vous aurez encore
besoin d'une phase d'assemblage (pensez vos m<>thodes m<>tier comme ayant un contrat strict avec la
couche de pr<70>sentation <20> propos de quelles donn<6E>es sont disponibles dans les objets d<>tach<63>s)
<20> moins que vous soyez pr<70>par<61>s <20> garder le contexte de
persistance (la session) ouvert <20> travers tout le processus de rendu de la vue.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pensez <20> abstraite votre logique m<>tier d'Hibernate.</term>
<listitem>
<para>
Cachez le m<>canisme d'acc<63>s aux donn<6E>es (Hibernate) derri<72>re une interface. Combinez les patterns
<emphasis>DAO</emphasis> et <emphasis>Thread Local Session</emphasis>. Vous pouvez m<>me avoir quelques
classes persist<73>es par du JDBC pur, associ<63>es <20> Hibernate via un <literal>UserType</literal> (ce conseil est
valable pour des applications de taille respectables ; il n'est pas valable pour une application
avec cinq tables).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>N'utilisez pas d'associations de mapping exotiques.</term>
<listitem>
<para>
De bons cas d'utilisation pour de vraies associations plusieurs-vers-plusieurs
sont rares. La plupart du temps vous avez besoin d'informations additionnelles
stock<63>es dans la table d'association.
Dans ce cas, il est pr<70>f<EFBFBD>rable d'utiliser deux associations un-vers-plusieurs vers une classe
de liaisons interm<72>diaire. En fait, nous pensons que la plupart des associations sont
de type un-vers-plusieurs ou plusieurs-vers-un, vous devez <20>tre tr<74>s attentifs lorsque
vous utilisez autre chose et vous demander si c'est vraiment n<>cessaire.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pr<EFBFBD>f<EFBFBD>rez les associations bidirectionnelles.</term>
<listitem>
<para>
Les associations unidirectionnelles sont plus difficiles <20> questionner.
Dans une grande application, la plupart des associations devraient <20>tre navigables dans les deux directions dans les requ<71>tes.
</para>
</listitem>
</varlistentry>
</variablelist>
</chapter>