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; } }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).
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; } }
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 :
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).
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
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 :
Cela me renvoie bien la bonne liste contenant une seule fois chaque enfant, mais dans le désordre !
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
C'est assez étrange, car la requête suivante :
me renvoie bien la liste correcte (bon nombre d'éléments, et ordonnée) mais ne charge pas la liste d'amis des enfants...
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
Je suis perdu... je ne sais pas comment faire...
Merci d'avance pour les pistes que vous pourrez me donner
Partager