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 :

Hibernate et Join Fetch


Sujet :

JPA Java

  1. #1
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut Hibernate et Join Fetch
    Bonjour tout le monde

    J'ai un problème avec une requête EJB QL : j'aimerai pouvoir charger une liste d'objets directement via la requête, pour des raisons de performance, sans passer par le FetchType.EAGER.

    Voici mes 2 classes (Entity Beans) :

    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
     
    @Entity
    public class ParentEntity implements Serializable {
     
        private int id;
        private List<ChildEntity> children;
     
        /** Creates a new instance of ParentEntity */
        public ParentEntity () {
        }
     
        /**
         * Gets the id of this ParentEntity .
         * @return the id
         */
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        public int getId() {
            return this.id;
        }
     
        /**
         * Sets the id of this ParentEntity to the specified value.
         * @param id the new id
         */
        public void setId(int id) {
            this.id = id;
        }
     
        @OneToMany(cascade = {CascadeType.ALL})
        @IndexColumn(name = "index")
        public List<ChildEntity> getChildren() {
            return children;
        }
     
        public void setChildren(List<ChildEntity> children) {
            this.children= children;
        }
     
       @Override
        public int hashCode() {
            return getId();
        }
     
        @Override
        public boolean equals(Object obj) {
            if (obj != null && obj instanceof ParentEntity) {
                return getId() == ((ParentEntity) obj).getId();
            }
     
            return false;
        }
    }
    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
     
    @Entity
    public class ChildEntity implements Serializable {
     
        private int id;
        private List<FriendEntity> friends;
     
        /** Creates a new instance of ChildEntity */
        public ChildEntity () {
        }
     
        /**
         * Gets the id of this ChildEntity .
         * @return the id
         */
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        public int getId() {
            return this.id;
        }
     
        /**
         * Sets the id of this ChildEntity to the specified value.
         * @param id the new id
         */
        public void setId(int id) {
            this.id = id;
        }
     
        @OneToMany(cascade = {CascadeType.ALL})
        @IndexColumn(name = "index")
        public List<FriendEntity> getFriends() {
            return friends;
        }
     
        public void setFriends(List<FriendEntity> friends) {
            this.friends= friends;
        }
     
       @Override
        public int hashCode() {
            return getId();
        }
     
        @Override
        public boolean equals(Object obj) {
            if (obj != null && obj instanceof ChildEntity) {
                return getId() == ((ChildEntity) obj).getId();
            }
     
            return false;
        }
    }
    L'exemple est simple : j'ai des parents (ParentEntity). Chaque parent a une liste ordonnée d'enfants (ChildEntity). Chaque enfant a à son tour une liste ordonnée d'amis (FriendEntity).

    Je souhaite pouvoir récupérer la liste des enfants connaissant l'id du parent, tout en chargeant la liste d'amis de ceux-ci. J'ai donc écrit cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT child 
    FROM ParentEntity parent, IN (parent.children) child LEFT JOIN FETCH child.friends 
    WHERE parent.id = ?0
    Le problème est que je récupère des enfants en double, je ne les récupère pas qu'une seule fois... En fait, je récupère tous les enfants du bon parent * leur nombre d'amis (s'il y a 4 enfants, et que chacun ont 3 amis, ma liste contient 3 fois la liste des enfants soit 12 éléments retournés).

    Je n'arrive donc pas à retourner cette liste proprement, le tout en conservant l'ordre (la liste des enfants est ordonnée).
    J'ai essayé ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT DISTINCT child 
    FROM ParentEntity parent, IN (parent.children) child LEFT JOIN FETCH child.friends 
    WHERE parent.id = ?0
    Cela me renvoie bien la bonne liste contenant une seule fois chaque enfant, mais dans le désordre !

    C'est assez étrange, car la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT child 
    FROM ParentEntity parent, IN (parent.children) child 
    WHERE parent.id = ?0
    me renvoie bien la liste correcte (bon nombre d'éléments, et ordonnée) mais ne charge pas la liste d'amis des enfants...

    Je suis perdu... je ne sais pas comment faire...

    Merci d'avance pour les pistes que vous pourrez me donner

  2. #2
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Finalement, j'ai fait autrement : j'ai récupéré le parent qui a sa liste d'enfants chargée, qui ont leurs listes d'amis chargées également.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT parent
    FROM ParentEntity parent 
    LEFT JOIN FETCH parent.children child 
    LEFT JOIN FETCH child.friends 
    WHERE parent.id = ?0
    Là, en faisant parent.getChildren() tout est correct : nombre + ordre

    Merci quand même !

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

Discussions similaires

  1. [Hibernate] Join fetch et set (one-to-many)
    Par TiMiD dans le forum Hibernate
    Réponses: 2
    Dernier message: 26/10/2007, 02h48
  2. [HQL]Problème avec double join fetch
    Par zev dans le forum Hibernate
    Réponses: 1
    Dernier message: 05/12/2006, 09h59
  3. [Hibernate]Problème de requete avec "join fetch"
    Par gauloiskiki dans le forum Hibernate
    Réponses: 4
    Dernier message: 21/06/2006, 09h54
  4. [Hibernate] Outer-join
    Par hum_dam dans le forum Hibernate
    Réponses: 3
    Dernier message: 25/08/2005, 17h53
  5. [Hibernate] Inner join dans hibernate
    Par Saloucious dans le forum Hibernate
    Réponses: 3
    Dernier message: 24/08/2005, 09h38

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