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

JPA Java Discussion :

Petite question sur le LAZY LOADING


Sujet :

JPA Java

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 139
    Points : 50
    Points
    50
    Par défaut Petite question sur le LAZY LOADING
    Bonjour,

    J'ai remarqué un problème lorsque je charge une liste d'entités avec une requête JPQL.
    Un exemple tout simple: une entité Personne a une entité Adresse en attribut, j'ai donc une annotation @OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY) de Personne vers Adresse.
    Cette annotation est sensée éviter le chargement de l'adresse lors d'une requête sur l'entité Personne mais étrangement, pour un findAllPersonnes() par exemple, j'ai constaté que pour n Personnes, n requêtes de sélection d'Adresse se lancent, générant de gros problèmes de performance.
    J'ai contourné le problème en chargeant en une seule requête les personnes et leurs adresses grâce aux join fetch mais ce n'est pas ce que je veux.
    Est-ce à cause du CascadeType.ALL?
    Merci de m'aider

  2. #2
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 139
    Points : 50
    Points
    50
    Par défaut
    Je viens de trouver quelque chose d'intéressant. Le LAZY LOADING ne marche que dans un conteneur J2EE.
    Dans mon cas je suis dans une application cliente J2SE. C'est surement ça le problème.

  3. #3
    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
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Je ne pense pas, tu as peut-être un fetch join dans le cas de ta requête findAllPersonnes() auquel cas, tu by-pass l'information FetchType.LAZY

  4. #4
    Expert confirmé
    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
    Points : 4 141
    Points
    4 141
    Par défaut
    Bizarre ton affaire.
    Tu as le lien d'où tu tires cela ?

  5. #5
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Points : 3 938
    Points
    3 938
    Par défaut
    Vraiment bizarre ton pb, car ca remet en cause même la politique de fonctionnement EAGER ou LAZY.
    peux tu nous faire voir la requete que tu faisais pour qu'il charge en même temps les adresses liées aux personnes?

  6. #6
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 139
    Points : 50
    Points
    50
    Par défaut
    source: http://wiki.eclipse.org/Using_Eclips...nk_JPA_Weaving

    méthode pour récupérer les personnes et leurs adresses et éviter le eager loading:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public List<Utilisateur> getAllUtilisateurs() {
            Query query = PersistanceUnit.getInstance().getEm().createQuery("SELECT distinct u FROM Utilisateur u join fetch u.compteVision join fetch u.adresse order by u.nom asc, u.prenom asc");
            query.setHint(QueryHints.FETCH, "join fetch u.compteVision.personne");
            query.setHint(QueryHints.FETCH, "join fetch u.compteVision.profil");
            return query.getResultList();
        }

  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
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Bon ben c'est clair, tu as bien un join fetch sur u.adresse, d'où la récupération des adresses dans ce cas.

  8. #8
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 139
    Points : 50
    Points
    50
    Par défaut
    La méthode que j'ai montré permet de charger toutes les données en une seule requête.
    Voici l'ancienne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public List<Utilisateur> getAllUtilisateurs() {
            Query query = PersistanceUnit.getInstance().getEm().createQuery("SELECT distinct u FROM Utilisateur u order by u.nom asc, u.prenom asc");
            return query.getResultList();
        }
    C'est elle qui me lance pour n utilisateurs, 5 requêtes de sélection pour charger les données en relation avec un utilisateur soit 5n requêtes!
    Mais comme je l'ai dit, le problème vient du fait que le Lazy loading ne fonctionne pas hors d'un conteneur. Il y a moyen de l'activer dans un environnement J2SE mais ça m'envoie sur un autre problème que j'ai posté à propos du weaving dynamique de EclipseLink: http://www.developpez.net/forums/d88...ploiement-ejb/

  9. #9
    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
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Bon, dans le principe, voilà comment ça se passe.
    Tout objet "attaché" peut traiter le lazy loading.
    Un objet "detaché" ou "nouveau" ne le peut pas.

    Il se trouve que pour les EJB, dès qu'on sort du conteneur (d'EJB), l'objet est "détaché".
    Ça, c'est le cas par défaut avec JTA.
    En pratique, on fait appel à une méthode d'un EJB (stateless) et à la sortie de la méthode, l'état est changé (dans les grandes lignes, ça peut être plus compliqué).
    Il est possible de passer par un mode dit "extended" pour faire différemment.
    Rien n'empêche de laisser la couche IHM acquérir une connexion et la libérer en fin de cycle.

    La question est : utilises-tu des EJB ou des DAO (java basic) ?

  10. #10
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 139
    Points : 50
    Points
    50
    Par défaut
    Dans mon cas, je suis dans une appli J2SE (le client contient l'implémentation de JPA) donc pas d'EJB, uniquement des DAO requettant la base à distance.
    Tout objet "attaché" peut traiter le lazy loading.
    A condition d'avoir le weaver activé.

    J'ai également codé une application .ear contenant des EJB permettant de fournir les même accès aux données. Le lazy loading marche bien avec Toplink (nous sommes dans ce cas dans un conteneur de GlassfishV3), mais sous EclipseLink, le weaver me retourne une exception que je ne comprend pas.

  11. #11
    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
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    weaver ? Connais pas... jamais utilisé... il semble que ce soit lié à Spring...

    C'est bien ton application JSE qui fait l'acquisition de la connexion, non ?
    Donc, tant que la connexion est ouverte, le lazy loading peut fonctionner.

    Avec le lazy loading, tu as des proxy vers les entités référencées, maintenant, je ne connais pas TopLink, je n'utilise qu'Hibernate, il y a peut-être des différences...

  12. #12
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 139
    Points : 50
    Points
    50
    Par défaut
    Avec le lazy loading, tu as des proxy vers les entités référencées, maintenant, je ne connais pas TopLink, je n'utilise qu'Hibernate, il y a peut-être des différences...
    Oui surement, il me semble que la notion de "weaver" apparait que pour TopLink et EclipseLink...
    Je ne connais pas vraiment tout le fonctionnement mais je sais qu'il est obligatoire pour le lazy loading et qu'on peut le paramétrer (statique, dynamique, etc.).
    Lorsque j'aurait compris pourquoi je n'arrive pas à déployer mes EJB avec le weaver d'EclipseLink activé, je reviendrai faire un topo. Merci pour ton aide.

Discussions similaires

  1. Petite Question sur le lazy loading
    Par Arthis dans le forum ASP.NET
    Réponses: 2
    Dernier message: 19/11/2008, 12h24
  2. [Visuel XP] Petite question sur le theme XP...
    Par ZoumZoumMan dans le forum C++Builder
    Réponses: 12
    Dernier message: 20/01/2005, 15h41
  3. petite question sur le composant IBX ...
    Par vbcasimir dans le forum Bases de données
    Réponses: 4
    Dernier message: 05/01/2005, 11h33
  4. Réponses: 3
    Dernier message: 08/12/2004, 14h58
  5. Petite question sur les performances de Postgres ...
    Par cb44 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 13/01/2004, 14h49

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