Cet article est la premire partie d'une srie traitant de la performance avec Hibernate et traite en particulier des stratgies de chargement.
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
I - Introduction..............................................................................................................................................................3 II - Prsentation de Hibernate..................................................................................................................................... 3 III - Problmes de performances avec Hibernate....................................................................................................... 3 IV - Prparation de l'environnement de test............................................................................................................... 3 IV-A - Cration du jeu de donnes avec Benerator.............................................................................................. 3 IV-B - Mapping et configuration de Hibernate....................................................................................................... 5 V - Prconisations......................................................................................................................................................13 VI - Rcuprer les informations de fonctionnement de Hibernate............................................................................ 14 VI-A - Tracer les requtes SQL........................................................................................................................... 14 VI-B - Tracer la valeur des paramtres hibernate............................................................................................... 16 VI-C - Tracer les transactions Hibernate............................................................................................................. 16 VI-D - Tracer toute acquisition de ressource JDBC............................................................................................ 17 VI-E - Statistiques Hibernate................................................................................................................................17 VI-F - JMX............................................................................................................................................................ 18 VII - Configuration du mapping................................................................................................................................. 18 VII-A - Stratgies de chargement........................................................................................................................ 18 VII-A-1 - Comment (quelle requte SQL est utilise).....................................................................................18 VII-A-1-a - Chargement par select............................................................................................................ 18 VII-A-1-a-i - Exemple 1 : Rcupration du propritaire d'un costume................................................. 18 VII-A-1-a-ii - Exemple 2 : Rcupration de la liste des costumes d'un consultant.............................. 19 VII-A-1-b - Chargement par jointure..........................................................................................................20 VII-A-1-b-i - Exemple 3 : Rcupration du propritaire d'un costume................................................. 21 VII-A-1-b-ii - Exemple 4 : Rcupration de la liste des costumes d'un consultant.............................. 24 VII-A-1-c - Chargement par lot..................................................................................................................25 VII-A-1-c-i - Exemple 5 : Rcupration du propritaire pour chaque costume.................................... 25 VII-A-1-d - Chargement par sous-select................................................................................................... 27 VII-A-1-d-i - Exemple 6 : Rcupration de la liste des costumes par consultant.................................27 VII-A-2 - Quand l'association est charge......................................................................................................29 VII-A-2-a - Chargement tardif.................................................................................................................... 29 VII-A-2-b - Chargement immdiat............................................................................................................. 31 VII-A-2-c - Chargement "super tardif" d'une collection............................................................................. 34 VII-A-2-d - Chargement tardif des attributs............................................................................................... 34 VIII - Exemples avec une plus grosse volumtrie............................................................................................... 35 VIII-1 - Exemple 7 : Chargement par lot........................................................................................................ 35 VIII-2 - Exemple 8 : Chargement par sous-select.......................................................................................... 35 VIII-3 - Exemple 9 : Exemple trs forte volumtrie..................................................................................... 36 IX - Conclusion..................................................................................................................................................... 36 X - Remerciements...............................................................................................................................................36 XI - Rfrences.................................................................................................................................................... 36
-2Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
I - Introduction
Maintenant que nous avons une mthode d'audit de performance et la possibilit de gnrer une base de donnes avec un gros volume, il est temps de regarder d'un peu plus prs certaines parties d'un programme Java EE. Dans cette srie d'articles, on commencera par la partie Hibernate en nous focalisant sur les performances et en particulier sur les stratgies de chargement pour ce premier article.
II - Prsentation de Hibernate
Comme il est dit dans la FAQ, Hibernate est un framework de mapping objet/relationnel qui permet de manipuler les donnes d'une base de donnes relationnelle sous forme d'objet. Pour plus d'informations sur Hibernate, il y a http://java.developpez.com/cours/?page=persistancecat#hibernate.
Afin d'avoir des traces les plus simples, nous nous contenterons d'un petit volume de donnes dans un premier temps. Commenons par crer les tables ncessaires.
-3Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
drop_tables.sql
DROP DROP DROP DROP
create_tables.sql
CREATE SEQUENCE seq_hibernate_id_gen start 1; CREATE TABLE t_couleur ( id_couleur int NOT NULL, nom_couleur varchar(64) NOT NULL, PRIMARY KEY (id_couleur) ); CREATE TABLE t_consultant ( id_consultant int NOT NULL, nom varchar(64), prenom varchar(64), email varchar(64), PRIMARY KEY (id_consultant) ); CREATE TABLE t_costume ( id_costume int NOT NULL, couleur_fk int NOT NULL, consultant_fk int NOT NULL, prix int NOT NULL, PRIMARY KEY (id_costume), CONSTRAINT t_costume_couleur_fk FOREIGN KEY (couleur_fk) REFERENCES t_couleur (id_couleur), CONSTRAINT t_costume_consultant_fk FOREIGN KEY (consultant_fk) REFERENCES t_consultant (id_consultant) );
Puis nous utiliserons un fichier CSV pour importer les couleurs. t_couleur.import.csv
<?xml version="1.0" encoding="iso-8859-1"?> <setup xmlns="http://databene.org/benerator/0.6.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://databene.org/benerator/0.6.3 http://databene.org/benerator-0.6.3.xsd"> <import platforms="db" /> <database id="db" url="jdbc:postgresql://localhost:5432/postgres" driver="org.postgresql.Driver" schema="public" user="benerator" password="benerator" batch="true" fetchSize="1000"/> <execute uri="drop_tables.sql" target="db" onError="ignore"/> <execute uri="create_tables.sql" target="db" optimize="true"/> <bean id="idGen" spec="new DBSeqHiLoGenerator('seq_hibernate_id_gen', 1, db)" /> <iterate source="t_couleur.import.csv" type="t_couleur" encoding="utf-8" consumer="db" /> <generate type="t_consultant" count="5" consumer="db" pageSize="1000" > <variable name="individu" generator="org.databene.domain.person.PersonGenerator" dataset="FR" locale="fr"/> <id name="id_consultant" generator="idGen" />
-4Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
hibernatePerf.xml
<attribute name="prenom" script="individu.givenName" /> <attribute name="nom" script="individu.familyName" /> <attribute name="email" script="individu.email" /> </generate> <generate type="t_costume" count="15" consumer="db" pageSize="1000"> <id name="id_costume" generator="idGen" /> <attribute name="prix" min="100" max="2000" /> <reference name="couleur_fk" targetType="t_couleur" source="db" distribution="random" /> <reference name="consultant_fk" targetType="t_consultant" source="db" distribution="random" cyclic="true" /> </generate> </setup>
-5Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
-6Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
-7Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
-8Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
-9Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
- 10 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
- 11 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
- 12 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
V - Prconisations
Mes prconisations sont. Toujours dvelopper avec Hibernate avec les traces actives et ne pas croire que Hibernate va optimiser les requtes par magie. Initialiser les relations en mode diffr/lazzy. Puis au cas par cas s'assurer que ce mode de chargement ne gnre pas les problmes dits de N+1 ou les produits cartsiens. Optimiser les modes de chargement en utilisant les techniques de chargement par jointure, chargement par sous select...
- 13 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Une des premires choses faire est d'activer les logs de Hibernate ou d'utiliser les bons outils afin de savoir ce qu'il se passe. Cela nous permettra de rcuprer les requtes SQL gnres pour affiner le tuning de la base de donnes (ajout d'index, optimisation des tables space...) et de valider le paramtrage de Hibernate. Regardons comment activer les traces de Hibernate.
Ou activer les proprits hibernate.show_sql et sql_comments dans le fichier hibernate.cfg.xml Le code suivant.
TCostume costume = (TCostume) session.load(TCostume.class, 4113); System.out.println(costume.getIdCostume()); System.out.println(costume.getTConsultant().getNom());
Afin de formater les requtes SQL, on pourra activer la proprit hibernate.format_sql dans le fichier hibernate.cfg.xml. Pour cela ajouter.
<property name="hibernate.format_sql">true</property>
- 14 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com) where tconsultan0_.id_consultant=?
Pour obtenir.
/* load hibernatep.TCostume */ select tcostume0_.id_costume as id1_1_0_, tcostume0_.consultant_fk as consultant2_1_0_, tcostume0_.couleur_fk as couleur3_1_0_, tcostume0_.prix as prix1_0_ from public.t_costume tcostume0_ where tcostume0_.id_costume=? /* load hibernatep.TConsultant */ select tconsultan0_.id_consultant as id1_2_0_, tconsultan0_.nom as nom2_0_, tconsultan0_.prenom as prenom2_0_, tconsultan0_.email as email2_0_ from public.t_consultant tconsultan0_ where tconsultan0_.id_consultant=?
Ne pas oublier de les dsactiver pour les autres tests de performances et pour la mise en production de l'application.
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com) DEBUG JDBCTransaction:103 - commit DEBUG JDBCTransaction:116 - committed JDBC Connection
Donnera.
INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO StatisticsImpl:463 StatisticsImpl:464 StatisticsImpl:465 StatisticsImpl:466 StatisticsImpl:467 StatisticsImpl:468 StatisticsImpl:469 StatisticsImpl:470 StatisticsImpl:471 StatisticsImpl:472 StatisticsImpl:473 StatisticsImpl:474 StatisticsImpl:475 StatisticsImpl:476 StatisticsImpl:477 StatisticsImpl:478 StatisticsImpl:479 StatisticsImpl:480 Logging statistics.... start time: 1280654979840 sessions opened: 1 sessions closed: 1 transactions: 1 successful transactions: 1 optimistic lock failures: 0 flushes: 1 connections obtained: 1 statements prepared: 2 statements closed: 2 second level cache puts: 0 second level cache hits: 0 second level cache misses: 0 entities loaded: 2 entities updated: 0 entities inserted: 0 entities deleted: 0
- 17 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com) INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO INFO StatisticsImpl:481 StatisticsImpl:482 StatisticsImpl:483 StatisticsImpl:484 StatisticsImpl:485 StatisticsImpl:486 StatisticsImpl:487 StatisticsImpl:488 StatisticsImpl:489 StatisticsImpl:490 StatisticsImpl:491 entities fetched (minimize this): 2 collections loaded: 0 collections updated: 0 collections removed: 0 collections recreated: 0 collections fetched (minimize this): 0 queries executed to database: 0 query cache puts: 0 query cache hits: 0 query cache misses: 0 max query time: 0ms
Si on ne veut pas autant d'informations, on peut spcifier celles que l'on veut. Par exemple : stats.getQueryCacheMissCount(), stats.getEntityDeleteCount(), stats.getCollectionLoadCount(), stats.getFlushCount()...
VI-F - JMX
Il est bien sur possible de rcuprer un certain nombre d'informations l'aide de JMX. Plus d'information sur http://docs.jboss.org/hibernate/core/3.5/reference/fr-FR/html/ performance.html#performance-monitoring
VII-A-1 - Comment (quelle requte SQL est utilise) VII-A-1-a - Chargement par select
Hibernate rcupre les donnes associe dans un second SELECT. C'est le comportement par dfaut de Hibernate. Attention le chargement par select est trs vulnrable au problme du N+1 selects.
- 18 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com) TCostume costume = (TCostume) session.load(TCostume.class, 4113); System.out.println(costume.getIdCostume()); TConsultant proprio = costume.getTConsultant(); System.out.println(proprio.getNom()); session.getTransaction().commit(); session.close();
select tcostume0_.id_costume as id1_1_0_, tcostume0_.consultant_fk as consultant2_1_0_, tcostume0_.couleur_fk as couleur3_1_0_, tcostume0_.prix as prix1_0_ from public.t_costume tcostume0_ where tcostume0_.id_costume=? select tconsultan0_.id_consultant as id1_0_0_, tconsultan0_.nom as nom0_0_, tconsultan0_.prenom as prenom0_0_, tconsultan0_.email as email0_0_ from public.t_consultant tconsultan0_ where tconsultan0_.id_consultant=?
La premire rcupre les informations du costume recherch et la 2me les informations sur le propritaire. C'est dommage d'utiliser 2 requtes SQL pour ce rsultat alors qu'une seul aurait pu suffire. C'est dans ce cas la que la stratgie de chargement par jointure joue un rle.
- 19 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com) for (Iterator iter = sets.iterator(); iter.hasNext();) { TCostume costume = (TCostume) iter.next(); System.out.println(costume.getIdCostume()); }
Gnrera 2 requtes SQL (une pour rcuprer l'identifiant du costume associ au consultant avec l'identifiant 4108, puis une pour rcuprer les informations de la table costume). C'est le problme dits de N+1
select tconsultan0_.id_consultant as id1_0_, tconsultan0_.nom as nom0_, tconsultan0_.prenom as prenom0_, tconsultan0_.email as email0_ from public.t_consultant tconsultan0_ select tcostumes0_.consultant_fk as consultant2_1_, tcostumes0_.id_costume as id1_1_, tcostumes0_.id_costume as id1_1_0_, tcostumes0_.consultant_fk as consultant2_1_0_, tcostumes0_.couleur_fk as couleur3_1_0_, tcostumes0_.prix as prix1_0_ from public.t_costume tcostumes0_ where tcostumes0_.consultant_fk=?
Il faudra faire attention se retrouver avec des requtes trop complexes comportant trop de jointure.
- 20 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
select tcostume0_.id_costume as id1_1_1_, tcostume0_.consultant_fk as consultant2_1_1_, tcostume0_.couleur_fk as couleur3_1_1_, tcostume0_.prix as prix1_1_, tconsultan1_.id_consultant as id1_0_0_, tconsultan1_.nom as nom0_0_, tconsultan1_.prenom as prenom0_0_, tconsultan1_.email as email0_0_ from public.t_costume tcostume0_ inner join public.t_consultant tconsultan1_ on tcostume0_.consultant_fk=tconsultan1_.id_consultant where tcostume0_.id_costume=?
Donc si on sait que l'on va utiliser les informations des tables jointes, l'utilisation de la stratgie par jointure est une bonne ide. Mais comme cela dpend des cas, il est plus judicieux de surcharger pour une transaction particulire l'aide de left join fetch dans les requtes HQL.
- 21 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com) Query query = session.createQuery("from TCostume where idCostume=4113"); Iterator it = query.list().iterator(); while (it.hasNext()) { TCostume costume = (TCostume) it.next(); System.out.println(costume.getIdCostume() + " : " + costume.getTConsultant().getNom()); }
Produira.
select tcostume0_.id_costume as id1_1_, tcostume0_.consultant_fk as consultant2_1_, tcostume0_.couleur_fk as couleur3_1_, tcostume0_.prix as prix1_ from public.t_costume tcostume0_ where tcostume0_.id_costume=4113 select tconsultan0_.id_consultant as id1_0_0_, tconsultan0_.nom as nom0_0_, tconsultan0_.prenom as prenom0_0_, tconsultan0_.email as email0_0_ from public.t_consultant tconsultan0_ where tconsultan0_.id_consultant=?
On aura.
- 22 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
select tcostume0_.id_costume as id1_1_0_, tconsultan1_.id_consultant as id1_0_1_, tcostume0_.consultant_fk as consultant2_1_0_, tcostume0_.couleur_fk as couleur3_1_0_, tcostume0_.prix as prix1_0_, tconsultan1_.nom as nom0_1_, tconsultan1_.prenom as prenom0_1_, tconsultan1_.email as email0_1_ from public.t_costume tcostume0_ left outer join public.t_consultant tconsultan1_ on tcostume0_.consultant_fk=tconsultan1_.id_consultant where tcostume0_.id_costume=4113
- 23 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Et cette fois ci, on n'a plus qu'une seule requte SQL au lieu de 2
select tconsultan0_.id_consultant as id1_0_1_, tconsultan0_.nom as nom0_1_, tconsultan0_.prenom as prenom0_1_, tconsultan0_.email as email0_1_, tcostumes1_.consultant_fk as consultant2_3_, tcostumes1_.id_costume as id1_3_, tcostumes1_.id_costume as id1_1_0_, tcostumes1_.consultant_fk as consultant2_1_0_, tcostumes1_.couleur_fk as couleur3_1_0_, tcostumes1_.prix as prix1_0_ from public.t_consultant tconsultan0_ left outer join public.t_costume tcostumes1_ on tconsultan0_.id_consultant=tcostumes1_.consultant_fk where tconsultan0_.id_consultant=?
- 24 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
On aura 6 requtes SQL (une requte qui rcupre la liste des costumes et 5 autres pour rcuprer les noms des consultants).
select tcostume0_.id_costume as id1_1_, tcostume0_.consultant_fk as consultant2_1_, tcostume0_.couleur_fk as couleur3_1_, tcostume0_.prix as prix1_ from public.t_costume tcostume0_ select tconsultan0_.id_consultant as id1_0_0_, tconsultan0_.nom as nom0_0_, tconsultan0_.prenom as prenom0_0_, tconsultan0_.email as email0_0_ from public.t_consultant tconsultan0_ where tconsultan0_.id_consultant=?
Maintenant modifions le fichier de mapping de TConsultant afin d'utiliser le chargement par lot l'aide du paramtre batch-size.
<class name="hibernateperfarticle.TConsultant" batchsize="10" table="t_consultant" schema="public">
Et nous obtenons seulement 2 requtes (une requte qui rcupre la liste des costumes et une pour rcuprer tous les consultants).
- 25 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
select tcostume0_.id_costume as id1_1_, tcostume0_.consultant_fk as consultant2_1_, tcostume0_.couleur_fk as couleur3_1_, tcostume0_.prix as prix1_ from public.t_costume tcostume0_ select tconsultan0_.id_consultant as id1_0_0_, tconsultan0_.nom as nom0_0_, tconsultan0_.prenom as prenom0_0_, tconsultan0_.email as email0_0_ from public.t_consultant tconsultan0_ where tconsultan0_.id_consultant in ( ?, ?, ?, ?, ? )
- 26 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
On aura 6 requtes SQL (une pour rcuprer la liste des consultants, puis une par consultant afin de rcuprer ses costumes)
select tconsultan0_.id_consultant as id1_0_, tconsultan0_.nom as nom0_, tconsultan0_.prenom as prenom0_, tconsultan0_.email as email0_ from public.t_consultant tconsultan0_ select tcostumes0_.consultant_fk as consultant2_1_, tcostumes0_.id_costume as id1_1_, tcostumes0_.id_costume as id1_1_0_, tcostumes0_.consultant_fk as consultant2_1_0_, tcostumes0_.couleur_fk as couleur3_1_0_, tcostumes0_.prix as prix1_0_ from public.t_costume tcostumes0_ where tcostumes0_.consultant_fk=?
- 27 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
select tconsultan0_.id_consultant as id1_0_, tconsultan0_.nom as nom0_, tconsultan0_.prenom as prenom0_, tconsultan0_.email as email0_ from public.t_consultant tconsultan0_ select tcostumes0_.consultant_fk as consultant2_1_, tcostumes0_.id_costume as id1_1_, tcostumes0_.id_costume as id1_1_0_, tcostumes0_.consultant_fk as consultant2_1_0_, tcostumes0_.couleur_fk as couleur3_1_0_, tcostumes0_.prix as prix1_0_ from public.t_costume tcostumes0_ where tcostumes0_.consultant_fk in ( select tconsultan0_.id_consultant
- 28 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com) from )
public.t_consultant tconsultan0_
Activons les bons logs. Comme il est indiqu dans les logs, on ne charge dans un premier temps que les informations du consultant.
/* load hibernatep.TConsultant */ select tconsultan0_.id_consultant as id1_2_0_, tconsultan0_.nom as nom2_0_, tconsultan0_.prenom as prenom2_0_, tconsultan0_.email as email2_0_ from public.t_consultant tconsultan0_ where tconsultan0_.id_consultant=?
Mettons un point d'arrt avant la rcupration des costumes et lanons le programme en mode debug..
- 29 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Comme on peut le voir, la 2me requte SQL n'est pas excute. Puis lorsqu'on a besoin des informations des costumes, la requte SQL est excut.
- 30 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
- 31 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Afin de bien le confirmer, on excute le code suivant tout seul en commentant les autres lignes.
TConsultant consultant = (TConsultant) session.get(TConsultant.class, 4108);
- 32 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Donc si on n'a pas besoins des dtails des costumes, le chargement immdiat est pnalisant car il va excuter une requte qui ne sert rien. Par contre dans le cas contraire, cela revient au mme car on aura les 2 mme requtes SQL. Si on ne veut qu'une seule requte qui rcupre toutes les informations il faut utiliser le chargement par jointure comme vu prcdemment. Donc le chargement immdiat est utiliser avec prcaution car on peu se retrouver avec normment de requtes SQL excut alors que seul la 1re est utile. On verra plus loin avec une volumtrie plus importante que cela peut poser de gros problme. Mais avant cela, ajoutons un chargement immdiat entre TCouleur et TCostumes et excutons le mme code que celui de la partie "chargement tardif".
<many-to-one name="TCouleur" class="hibernatep.TCouleur" fetch="select" lazy="false">
Cette fois ci on obtient beaucoup plus de requtes SQL car pour chaque costume on rcupre sa couleur.
/* load hibernatep.TConsultant */ select tconsultan0_.id_consultant as id1_2_0_, tconsultan0_.nom as nom2_0_, tconsultan0_.prenom as prenom2_0_, tconsultan0_.email as email2_0_ from public.t_consultant tconsultan0_ where tconsultan0_.id_consultant=? /* load one-to-many hibernatep.TConsultant.TCostumes */ select tcostumes0_.consultant_fk as consultant2_1_, tcostumes0_.id_costume as id1_1_, tcostumes0_.id_costume as id1_1_0_, tcostumes0_.consultant_fk as consultant2_1_0_, tcostumes0_.couleur_fk as couleur3_1_0_, tcostumes0_.prix as prix1_0_ from public.t_costume tcostumes0_ where tcostumes0_.consultant_fk=? /* load hibernatep.TCouleur */ select tcouleur0_.id_couleur as id1_0_0_, tcouleur0_.nom_couleur as nom2_0_0_ from public.t_couleur tcouleur0_ where tcouleur0_.id_couleur=? /* load hibernatep.TCouleur */ select tcouleur0_.id_couleur as id1_0_0_, tcouleur0_.nom_couleur as nom2_0_0_ from public.t_couleur tcouleur0_ where tcouleur0_.id_couleur=? /* load hibernatep.TCouleur */ select tcouleur0_.id_couleur as id1_0_0_, tcouleur0_.nom_couleur as nom2_0_0_ from public.t_couleur tcouleur0_ where tcouleur0_.id_couleur=?
- 33 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Une fois en mode "super tardif", on aura toujours 2 requtes SQL mais la 2me sera plus "lgre".
<set name="TCostumes" inverse="true" lazy="extra"> /* load hibernatep.TConsultant */ select tconsultan0_.id_consultant as id1_2_0_, tconsultan0_.nom as nom2_0_, tconsultan0_.prenom as prenom2_0_, tconsultan0_.email as email2_0_ from public.t_consultant tconsultan0_ where tconsultan0_.id_consultant=? select count(id_costume) from public.t_costume where consultant_fk =?
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Une autre solution est d'utiliser les projections pour ne charger que les attributs que l'on veut. Par exemple avec l'API Criteria, pour ne charger que l'identifiant et le nom des consultants.
List listeId = session.createCriteria(TConsultant.class). setProjection( Projections.projectionList() .add(Projections.property("idConsultant")) .add(Projections.property("nom"))) .list();
Donnera en SQL
/* criteria query */ select this_.id_consultant as y0_, this_.nom as y1_ from public.t_consultant this_
Et 3 000 de costumes.
<generate type="t_costume" count="3000" consumer="db" pageSize="1000">
- 35 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/
Hibernate et performance partie 1 : stratgies de chargement par Antonio Gomes Rodrigues (arodrigues.developpez.com)
Attention, il faut laisser un peu de temps Benerator pour gnrer cette volumtrie (sur ma machine, il gnre environ 4 600 000 lignes par heure).
IX - Conclusion
Comme on a pu le voir, un paramtrage plus fin des stratgies de chargement d'Hibernate permet d'optimiser notre application en rduisant le nombre de requtes SQL gnres. Mais il faut faire attention car rduire le nombre de requtes SQL n'est pas toujours la meilleur solution si on se retrouve avec des requtes trop complexes et consommatrices. En effet la 2me piste d'optimisation est la gestion des caches de Hibernate qu'il faudra combiner avec la gestion des stratgies de chargement. C'est ce que nous verrons lors du prochain article consacr Hibernate.
X - Remerciements
Merci ram-0000 pour sa relecture orthographique
XI - Rfrences
Documentation officiel : http://www.hibernate.org/docs.html Documentation sur dvp.com : http://java.developpez.com/cours/?page=persistance-cat#hibernate Site officiel de Benerator : http://databene.org/databene-benerator
- 36 Les sources prsentes sur cette pages sont libres de droits, et vous pouvez les utiliser votre convenance. Par contre la page de prsentation de ces sources constitue une oeuvre intellectuelle protge par les droits d'auteurs. Copyright 2010 - Gomes Rodrigues Antonio. Aucune reproduction, mme partielle, ne peut tre faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu' 3 ans de prison et jusqu' 300 000 E de dommages et intrts.
http://arodrigues.developpez.com/tutoriels/java/performance/hibernate-performance-part1-strategies-chargement/