From
doit donner la liste des entités sur lesquelles la requête doit être exécutée. Dans tous les cas, on doit donner au moins une entité. Une entité peut être désignée par le nom complet de sa classe, ou son nom, qui joue le rôle d'alias. Ce nom est la valeur de l'attribut
name
de l'annotation
@Entity
.
Rappelons enfin deux choses :
@MappedSuperClass
n'est pas une entité, on ne peut donc pas faire de requête dessus ;
Personne
, étendue par
Marin
et
Capitaine
. Ces trois classes sont concrètes, et sont des entités. Une quatrième classe,
Bateau
, porte une relation
passager
, de type
Personne
, annotée
@OneToOne
, et une deuxième,
equipage
, également de type
Passager
, annotée
@OneToMany
On remarquera que cet exemple porte une relation polymorphique (
passager
peut recevoir des instances de nos trois classes
Passager
,
Marin
et
Capitaine
. On choisira une strategie
JOINED
pour la mise en base.
Exemple 43. Une première jointure JPQL implicite
select bateau.passager from Bateau bateau where bateau.nom = :nom
left outer join
) entre la table
Bateau
et la table
Personne
. Si l'on n'avait pas ajouter la clause
where
, on aurait obtenu en résultat la liste de toutes les personnes qui sont passagers d'un bateau.
On aurait pu écrire une jointure explicite de la façon suivante :
Exemple 44. Une première jointure JPQL explicite
select personne from Bateau bateau join bateau.passager personne where bateau.nom = :nom
Exemple 45. Une jointure externe JPQL
select bateau from Bateau bateau left join bateau.passager personne where bateau.nom like :nom
Exemple 46. SQL généré par une jointure externe JPQL
SELECT t1.ID, t1.NOM, t1.PASSAGER_ID FROM BATEAU t1 LEFT OUTER JOIN PERSONNE t0 ON (t0.ID = t1.PASSAGER_ID) WHERE (t1.NOM LIKE ?)
left
de notre requête JPQL, on obtient le code généré suivant :
Exemple 47. SQL généré sans jointure externe JPQL
SELECT t1.ID, t1.NOM, t1.PASSAGER_ID FROM PERSONNE t0, BATEAU t1 WHERE ((t1.NOM LIKE ?) AND (t0.ID = t1.PASSAGER_ID))
fetch
permet de lire les objets en relation directement, et donc de faire l'économie de cet aller et retour. Modifions notre requête afin de mettre en œuvre cette technique.
Exemple 48. Jointure
fetch
select bateau from Bateau bateau left join fetch bateau.passager where bateau.nom like :nom
fetch
se place à droite du mot-clé
join
;
join
.
Exemple 49. SQL généré pour une jointure
fetch
SELECT t1.ID, t1.NOM, t1.PASSAGER_ID, t0.ID, t0.DTYPE, t0.PRENOM, t0.NOM FROM BATEAU t1 LEFT OUTER JOIN PERSONNE t0 ON (t0.ID = t1.PASSAGER_ID) WHERE (t1.NOM LIKE ?)On constate que les champs de
Personne
(
nom
et
prenom
) ont été ajoutés à la requête, ce qui va autoriser la construction de la relation
passager
de chaque instance de
Bateau
dès l'exécution de cette requête.
where
, même dans le cas où cette clause
where
n'existe pas.
Considérons par exemple la requête JPQL suivante.
Exemple 50. Requête jointe sans clause
where
select bateau from Bateau bateau join bateau.passager personne
passager
, la jointure sera établie dans le SQL généré. En particulier, si aucune instance de
Personne
ne se trouve en base, aucun
bateau
ne sera sélectionné par cette requête.