IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Hibernate & performance


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Sr. Software Engineer
    Inscrit en
    Août 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Software Engineer

    Informations forums :
    Inscription : Août 2007
    Messages : 169
    Par défaut Hibernate & performance
    Bonjour,

    j'aimerais savoir comment améliorer les performance de mon application qui tourne avec hibernate. maintenant la BD a pris du volume et tout rame au lancement.
    J'ai lu des trucs sur LAZY/EAGER et j'aimerais avoir des avis sur les stratégies à utiliser car j'ai une méthode Session.findAll(maClass.class) qui prends près de 10mn pour afficher 50.000 instances (c'est pas beaucoup comme données pourtant!)

    merci.

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    50.000 objets en mémoire, à 1k l'objet (ce qui n'est pas grand chose, evidement tout dépend du nombre de champs de tes objet + les surcouches d'hibernate), tu pompe 48M de données pour les mettre en mémoire. Si t'as besoin d'avoir 50.000 row en mémoire, regarde plutot du cotés des requete hibernate qui te retournent des tableaux plutot que des objets hibernante.


    De plus faut voir dans quelle mesure c'est pas ton affichage qui prendrait 9m30 et le pompage base de données 30 secondes (ce qui cadrerais plus avec les 50.000 objets.

  3. #3
    Membre confirmé
    Profil pro
    Sr. Software Engineer
    Inscrit en
    Août 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Software Engineer

    Informations forums :
    Inscription : Août 2007
    Messages : 169
    Par défaut
    merci,

    je regarderai dans cette direction pour voir ce que ça donne. En passant ma BD est supposé vite grossir et devrait accueillir des dizaine de millions de d'instances.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Par défaut
    C'est toujours le même problème, est-il obligatoire d'afficher autant de données en même temps ?
    Quand on a beaucoup de données, on utilise la pagination par exemple.

  5. #5
    Membre confirmé
    Profil pro
    Sr. Software Engineer
    Inscrit en
    Août 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Software Engineer

    Informations forums :
    Inscription : Août 2007
    Messages : 169
    Par défaut
    tchize_, juste précision supplémentaire:

    j'ai fait une accès direct via JDBC et l'affichage est instantané. Je conclu que la lenteur provient d'hibernate et pas de l'affichage

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    on peux voir les deux code ainsi que le mapping de la classe? Sache aussi que hibernate fait beaucoup plus que réceptionner les données, il crée des proxy pour chaque classe, initialise les champs par réflection, associe les classe à la session dans un map, charge éventuellement ce qui doit être chargé en non-lazy.

    48M de données en instantané, t'as une bon réseau toi

  7. #7
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Quelle stratégie de chargement utilises-tu (EAGER) ?

    Il est certain qu'avec un fetch EAGER, tu peux être amené à charger tout le graphe objets en mémoire, ça n'aide pas beaucoup de tester une requête SQL du type "select * from maTable" pour comparer par rapport à un "from MaTable.class", sauf si tu as mis fetch = LAZY.

    Peux-tu préciser ?

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre confirmé
    Profil pro
    Sr. Software Engineer
    Inscrit en
    Août 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Software Engineer

    Informations forums :
    Inscription : Août 2007
    Messages : 169
    Par défaut
    Ci-dessous un mapping de deux tables (mon système en compte une cinquantaine)


    Mapping :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    <class name="Document" table="document">
     
    		<id name="Id" type="integer">
    		 <column name="id" sql-type="int(4)"/>
    		 <generator class="increment"/>
    		</id>
     
    		<property name="Name"	type="string">
    		<column name="name" sql-type="char(50)" not-null="true"/>
    		</property>
     
     
     
    		<!-- association inverse doc 1:N Phrase-->
     
    		<set name="Sentences"  inverse="true" cascade="all-delete-orphan">
    		    <key column="doc_id"/>
    		    <one-to-many class="Sentence"/> 
     
    		</set>
     
     
             <!-- association  Corpus -->
    	<many-to-one name="Corpus" class="Corpus" column="corpus_id"/>
     
     
    	</class>
     
     
     
    <class name="Sentence" table="sentence">
     
    		<id name="Id" type="integer">
    		 <column name="id" sql-type="int(4)"/>
    		 <generator class="increment"/>
    		</id>
     
    		<property name="Content"	type="string">
    		<column name="content" sql-type="char(300)" not-null="true"/>
    		</property>
     
     
    		<!-- association doc -->
    		<many-to-one name="Document" class="Document" column="doc_id" />



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
     
    public class Test {
     
     
    	public static java.util.List findAll (Class referenceClass,Session s) throws HibernateException {
    		Criteria crit = createCriteria(s,referenceClass);
     
    		return crit.list();
    	}
     
     
     
    	public static void main(String[] args) {
    	// creation d'une session	   
    	Session s= hibernateUtil.getCurrentSession();	
     
          //recherche de toutes les instances de la classe Document
           List elts= findAll(Document.class, s); // c'est ici que ca rame
     
    	}
     
    }
    Pour le moment mon application fonctionne en localhost et je l'ai développé avec Hibernate 2 et j'ai laissser son EAGER par défaut.. Je voulais éviter les accès répétitifs à la BD. Maintenant je pense que c'est pour cela que l'application rame.
    Quelle serait la bonne stratégie dans ce cas?

    merci

  9. #9
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Par défaut
    Question à part, pourquoi n'utilises tu pas Hibernate 3 ?

    Il faut que tu mettes tes collections à lazy = true, qui est la valeur par défaut dans Hibernate 3 mais pas dans la 2.

    Après, c'est à toi de jongler entre le nombre de données remontées, le nombre affichées, etc...
    Encore une fois, je ne connais pas ton interface, mais il n'est peut-être pas utile de remonter autant d'objets d'un coup.
    Ou alors, les remonter, mais sans les collections associées, qui seraient chargées ultérieurement.

  10. #10
    Membre confirmé
    Profil pro
    Sr. Software Engineer
    Inscrit en
    Août 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Software Engineer

    Informations forums :
    Inscription : Août 2007
    Messages : 169
    Par défaut
    merci. c'était effectivement une erreur de dtd.
    maintenant tout compile mais encore une erreur. voici ma classe HibernateUtil.java en charge d'initialiser la session.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    public class HibernateUtil{
     
    private static SessionFactory sessionFactory;
    	private static Configuration config = new Configuration();
     
    	public static Configuration getConfig() {
    		return config;
    	}
     
    	public static SessionFactory getSessionFactory() {
    		return sessionFactory;
    	}
     
    	// build a sessionFactory using a configFile
             private static void buildSessionFactory(String configFileName) {
     
    		if (null == configFileName)
    			config.configure();
    		else {
    			config.configure(configFileName);
     
    			try {
    				// Create the SessionFactory from hibernate.cfg.xml
     
    				sessionFactory = config.buildSessionFactory();
     
    			} catch (Throwable ex) {
    				// Make sure you log the exception, as it might be swallowed
    				System.err.println("Initial SessionFactory creation failed."
    						+ ex);
    				throw new ExceptionInInitializerError(ex);
    			}
    		}
    	}
     
    	/**
             * Return a new Session object that must be closed when the work has been
             * completed.
             * 
             * @return the active Session
             */
    	public static Session getCurrentSession() throws HibernateException {
    		return getSessionFactory().getCurrentSession();
    	}
     
    	/**
             * Configure the session factory by reading hibernate config file
             * 
             * @param configFileName
             *            the name of the configuration file
             */
    	public static void initialize(String configFileName){
     
          buildSessionFactory(configFileName);
    	}
     
     
    }

    quand j'execute je recois l'erreur suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    INFO: building session factory
    Initial SessionFactory creation failed.java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(Z)V
    Exception in thread "main" java.lang.ExceptionInInitializerError
    	at myProject.session.model.impl.HibernateUtil.buildSessionFactory(HibernateUtil.java:155)
    	at myProject.session.model.impl.HibernateUtil.initialize(HibernateUtil.java:178)
    	at monPackage.session.model.impl.SessionDafoeImpl.<init>(SessionDafoeImpl.java:39)
    	at myProject.factory.model.impl.SessionFactoryImpl.getSessionDafoe(SessionFactoryImpl.java:15)
    	at myProject.samples.TerminologicalSamples.getAllTermSample(TerminologicalSamples.java:215)
    	at myProject.samples.TerminologicalSamples.main(TerminologicalSamples.java:822)
    Caused by: java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(Z)V
    	at net.sf.cglib.core.DebuggingClassWriter.<init>(DebuggingClassWriter.java:47)
    	at net.sf.cglib.core.DefaultGeneratorStrategy.getClassWriter(DefaultGeneratorStrategy.java:30)
    	at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:24)
    	at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    	at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
    	at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:117)
    	at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108)
    	at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104)
    	at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69)
    	at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.getProxyFactory(CGLIBLazyInitializer.java:117)
    	at org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory.postInstantiate(CGLIBProxyFactory.java:43)
    	at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory(PojoEntityTuplizer.java:162)
    	at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:135)
    	at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:55)
    	at org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping.<init>(EntityEntityModeToTuplizerMapping.java:56)
    	at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:295)
    	at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:434)
    	at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:109)
    	at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)
    	at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:226)
    	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)
    	at myProject.session.model.impl.HibernateUtil.buildSessionFactory(HibernateUtil.java:149)
    	... 5 more
    Quelqu'un aurait-il une solution?
    J'aimerais aussi savoir si c'est normale que dans la trace on retrouve des references à hibernate 2 (net.sf. )

  11. #11
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    il n'y a pas de référence à hibernate 2 dans ta trace. C'est net.sf.cglib qu'on retrouve dedans, ca correspond à la librairie cglib. Dans ton cas, c'est ta librairie asm et/ou cglib qui n'est pas dans la version requise par hibernate.

  12. #12
    Membre confirmé
    Profil pro
    Sr. Software Engineer
    Inscrit en
    Août 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Software Engineer

    Informations forums :
    Inscription : Août 2007
    Messages : 169
    Par défaut
    J'avance dans ma migration vers Hibernate 3 avec quelques constat pour ceux que ca peut aider:

    En fait je suis dans un contexte Eclipse RCP. j'ai justement constaté qu'Eclipse importait plutot sa propre library asm (en calculant les dépendance: j'ai désactivé cet import).
    ca compile mais renvoi l'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    org.hibernate.HibernateException: No CurrentSessionContext configured
    Et en lisant http://www.mastertheboss.com/en/hibe...-tutorial.html j'ai rajouté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <property name="current_session_context_class">thread</property>
    Ce dont je n'avait pas besoin avec hibernate 2.

    Par ailleurs j'ai constater deux choses:

    1 Hibernate3 impose la création d'une transaction pour les requêtes selection (par exemple avec Criteria(...).list()) contrairement à hibernate 2

    2 Le comit de la transaction créer pour la requete de sélection faire automatiquement la session ouverte ==> impossible de charger les collections.

    Maintenant je vais essayer de trouver une bonne stratégie de gestion la mémoire et reste preneur pour toutes idées.

    merci

  13. #13
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par henpower Voir le message
    1 Hibernate3 impose la création d'une transaction pour les requêtes selection (par exemple avec Criteria(...).list()) contrairement à hibernate 2
    T'es sur là, jai jamais constaté ce phénomène. J'ai ce code ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    session.createCriteria(c).list();
    sur une session qui retourne directement du createSession de la factory, aucun soucis! Et je suis en hibernate 3.

    2 Le comit de la transaction créer pour la requete de sélection faire automatiquement la session ouverte ==> impossible de charger les collections.
    Encore une fois étrange, je fais ici des commit sur des transaction, ca ne ferme pas mes sessions.[/QUOTE]

  14. #14
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Par défaut
    Tout dépend de comment tu gères ta session.
    Est-elle rattachée à un thread, un contexte transactionnel, etc...

    Pour éviter ton problème de chargement sur les collections, tu peux :
    - charger tes collections avant ton commit
    - faire une session (longue) pour la lecture, qui reste ouverte en permanence
    et de petites sessions courtes pour l'ecriture de données.
    Il y avait un exemple d'application lourde avec Hibernate développée par un membre de l'équipe Hibernate qui expliquait ceci, mais je n'ai pas retrouvé le lien.

  15. #15
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Par défaut
    J'ai retrouvé un lien qui peut être intéressant.
    http://in.relation.to/Bloggers/HibernateAndSwingDemoApp

  16. #16
    Membre confirmé
    Profil pro
    Sr. Software Engineer
    Inscrit en
    Août 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Software Engineer

    Informations forums :
    Inscription : Août 2007
    Messages : 169
    Par défaut
    merci pour le lien fr1man et tes propositions.
    dis tchize_ est ce que le problème ne viendrait pas de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <property name="current_session_context_class">thread</property>
    Je suis autant surpris que toi par la fermeture des sessions et l'obligation de definir des transaction.
    Je vais regarder tout de près. En fait dans le projet sur lequel je bosse je suis chargé d'implementer la couche d'accès au données pour des developpeurs d'IHM qui ne doivent pas savoir que l'implemenetation est celle d'hibernate.
    Je le dis au cas où vous auriez des propositions à me faire pour abstraire au maximum hibernate et controlé les temps de réponses.

    J'utilise hiberante 3.2.5.ga
    Merci

  17. #17
    Membre confirmé
    Profil pro
    Sr. Software Engineer
    Inscrit en
    Août 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Software Engineer

    Informations forums :
    Inscription : Août 2007
    Messages : 169
    Par défaut getCurrentSession() vs openSession()
    Finalement le problème était lié à la façon de créer ma session hibernate.
    j'utilisais la méthode getCurrentSession() qui se base sur pattern Session per Transaction. Voila pourquoi chaque commit() fermait automatique la session courante.
    En utilisant openSession() le problème est résolu.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Hibernate et performance CPU
    Par Sniper37 dans le forum Hibernate
    Réponses: 31
    Dernier message: 02/10/2009, 12h13
  2. Réponses: 8
    Dernier message: 21/11/2006, 11h54
  3. [Hibernate][Ibatis] Problème de performance..
    Par Saloucious dans le forum Hibernate
    Réponses: 2
    Dernier message: 29/10/2005, 13h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo