Vous êtes sur la page 1sur 16

Introduction

‰ Ce cours explique les problèmes de base qui se


posent quand on veut faire correspondre
Correspondance n les données contenues dans un modèle objet

Objet - Relationnel n avec les données contenues dans une base


de données relationnelle
Université de Nice Sophia-Antipolis ‰ Le cours sur JPA (Java Persistence API)
Version 1.0.1 – 15/9/07 donnera un exemple concret d’outil qui
Richard Grin automatise en grande partie cette
correspondance

R. Grin Mapping objet-relationnel page 2

Présupposé
Département
numéro : int Une classe
nom : String
lieu : String

Une association
‰ La base de données relationnelle manipulée ajouterEmployé(Employe) : void

1 +contient
Une classe-
par une application objet peut déjà exister au association
Agrégation
moment de la conception de l’application objet +subordonné Participation
appartient
Unidirectionnel 0..* 0..* fonctionP : String Multiplicité
‰ Le cours qui suit suppose plutôt que la base hierarchie
Employe
matricule : int
n’existe pas 0..1
nom : String
poste : String
Projet
0..* 0..* codeP : String
dateEmbauche : date
‰ Si ça n’est pas le cas, les adaptations à une +supérieur
salaire : double +participe
nomP : String

ajouterEmploye(Employe)
base existante sont le plus souvent pris en Rôle pour
getSuperieur()
setSuperieur(Employe)
getMatricule()
charge par les outils de mapping, au prix l’association
quelquefois d'un mapping un peu plus Héritage
complexe Commercial
commission : double
Directeur Administratif

setCommission(double)
R. Grin Mapping objet-relationnel page 3 R. Grin Mapping objet-relationnel page 4

2 paradigmes Quelques problèmes du


passage Relationnel ↔ Objet
‰ Les paradigmes objet et relationnel sont bien
distincts ‰ Identité des objets
‰ Le paradigme objet est plus riche ‰ Traduction des associations
‰ Dès qu’un modèle objet est complexe (de ‰ Traduction de l’héritage
l’héritage et beaucoup d’associations) il n’est ‰ Navigation entre les objets
pas simple de faire correspondre des objets
et des tables relationnelles

R. Grin Mapping objet-relationnel page 5 R. Grin Mapping objet-relationnel page 6

1
Problème de base
Plan
‰ Un objet a une structure complexe qui peut
être représentée par un graphe 1. Exemple simple de traduction d’une classe
‰ Le plus souvent ce graphe est un arbre dont la en une table
racine correspond à l’objet et les fils 2. Identification
correspondent aux valeurs des variables 3. Traduction des associations
d’instance qui sont persistantes
4. Traduction de l’héritage
‰ Il faut « aplatir » ce graphe pour le ranger dans
5. Récupération des objets associés à un objet
la base de données relationnelle sous une
forme tabulaire

R. Grin Mapping objet-relationnel page 7 R. Grin Mapping objet-relationnel page 8

Traduction d’une classe


en une table
‰ Dans les cas les plus simples une classe est
Exemple simple de traduite en une table
traduction d’une classe ‰ Chaque objet est conservé dans une ligne de la
table
en une table ‰ Exemple : la classe Département est traduite par
la table
DÉPARTEMENT(numéro, nom, lieu)

R. Grin Mapping objet-relationnel page 9 R. Grin Mapping objet-relationnel page 10

Création de la table en SQL

create table departement (


numero smallint
constraint pk_dept primary key, Identification
nom varchar(15),
lieu varchar(15))

R. Grin Mapping objet-relationnel page 11 R. Grin Mapping objet-relationnel page 12

2
Identification dans le monde Objet Identification dans le monde relationnel
‰ Tout objet est identifiable simplement dans ‰ Seules les valeurs des colonnes peuvent servir
les langages objets (adresse de à identifier une ligne
l’emplacement mémoire), indépendamment ‰ Si 2 lignes ont les mêmes valeurs, il est
des données qu’il contient impossible de les différencier
‰ 2 objets distincts peuvent avoir exactement ‰ Toute table devrait donc comporter une clé
les mêmes valeurs pour leurs propriétés primaire pour identifier une ligne parmi toutes
les autres lignes de la même table

R. Grin Mapping objet-relationnel page 13 R. Grin Mapping objet-relationnel page 14

Éviter les identificateurs significatifs Propriété « clé primaire »


pour les objets
‰ Rappel du cours de L3 : même si les lignes
d’une table peuvent être distinguées par leurs ‰ Faut-il ajouter aux objets une propriété pour
valeurs, une clé primaire sera souvent rajoutée représenter une clé primaire non significative ?
pour éviter les identificateurs significatifs ‰ Le plus souvent la réponse est positive
‰ Surtout si la clé significative est composée de
‰ En effet, elle pourra être utilisée par le code
plusieurs propriétés pour un accès rapide aux données ou par le
‰ Les SGBDs peuvent générer automatiquement code ou l’outil de mapping pour aider à gérer le
des nombres entiers comme clés primaires des mapping objet-relationnel
nouvelles lignes insérées (séquences ou ‰ En ce cas, si le code le permet, on évitera une
colonnes de type spécial) méthode « setId » public
R. Grin Mapping objet-relationnel page 15 R. Grin Mapping objet-relationnel page 16

Problème des duplications Exemple de duplication


‰ Un objet p1 de la classe Produit de code
‰ Une même ligne de la base de données ne « s003 » est créé en mémoire à l’occasion
doit pas être représentée par plusieurs objets d’une navigation à partir d’une ligne de
en mémoire centrale (ou alors le code doit le facture
savoir et en tenir compte) ‰ On peut retrouver le même produit en
‰ Si elle n’est pas gérée, cette situation peut navigant depuis une autre facture, ou en
conduire à des pertes de données cherchant tous les produits qui vérifient un
certain critère
‰ Une erreur serait de créer en mémoire
centrale un autre objet p2 indépendant du
premier objet p1 déjà créé
R. Grin Mapping objet-relationnel page 17 R. Grin Mapping objet-relationnel page 18

3
Pour éviter des duplications Objets « insérés »
‰ En mémoire, un objet « cache » (nommé
« unité de travail » par Fowler) conserve une ‰ Le modèle objet peut avoir une granularité plus
référence vers les objets utilisés fine que le modèle relationnel
‰ Lors d’une navigation ou d’une recherche dans ‰ Les instances de certaines classes peuvent
la base, le cache intervient : être sauvegardées dans la même table qu’une
n Si l’objet est référencé par le cache, celui-ci autre classe
le fournit ‰ Ces instances sont appelées des objets
n Sinon, l’objet est créé avec les données insérés (embedded) et ne nécessitent pas
récupérées dans la base, et ajouté au cache d’identificateur « clé primaire »
‰ Cette fonction est remplie par les sessions de
Hibernate et les gestionnaires d’entités de JPA
R. Grin Mapping objet-relationnel page 19 R. Grin Mapping objet-relationnel page 20

Exemple
‰ Une classe Adresse peut ne pas avoir de
correspondance sous la forme d’une table
séparée dans le modèle relationnel
‰ Les attributs de la classe Adresse sont
Traduction des associations
insérées dans la table qui représente la
classe Client
‰ Les objets de la classe Adresse n’ont pas
d’identification liée à la base de données

R. Grin Mapping objet-relationnel page 21 R. Grin Mapping objet-relationnel page 22

Les associations en objet Exemple pour une


association 1:N (ou N:1)
‰ Dans le code objet une association peut être
représentée par ‰ class Département {
private Collection<Employé> employes;
n une variable d’instance référençant l’objet
. . .
associé (association 1:1 ou N:1) }
n une variable d’instance de type collection ‰ class Employé {
ou map contenant les objets associés private Département département;
(association 1:N ou M:N) . . .
}
n une classe « association » (M:N)

R. Grin Mapping objet-relationnel page 23 R. Grin Mapping objet-relationnel page 24

4
Association en relationnel Exemple pour
une association 1:N
‰ Dans le monde relationnel, une association peut
être représentée par ‰ create table DEPT ( . . .)
n une ou plusieurs clés étrangères (associations ‰ create table EMPLOYE (
1:1, N:1 ou 1:N) . . .
num_dept integer references DEPT)
n une table association (associations M:N le plus
souvent)

Pour faciliter la lecture, la syntaxe est simplifiée pour les contraintes


(pas de nom de contrainte)
R. Grin Mapping objet-relationnel page 25 R. Grin Mapping objet-relationnel page 26

Navigabilité des associations - objet Navigabilité des associations -


‰ Dans un modèle objet, une association peut
relationnel
être bi ou unidirectionnelle ‰ Dans un schéma relationnel, une association
‰ Exemple d’association unidirectionnelle : la est toujours bidirectionnelle : on peut toujours
classe Employé a une variable d’instance « naviguer » vers l’autre bout de l’association
donnant son département mais la classe ‰ Par exemple, pour trouver les employés du
Département n’a pas de collection département 10 :
d’employés select matr, nomE from employe
‰ En partant d’un département, on n’a alors pas where dept = 10
de moyen simple de retrouver ses employés

R. Grin Mapping objet-relationnel page 27 R. Grin Mapping objet-relationnel page 28

Association binaire M:N - Objet


‰ On va d’abord étudier le cas des associations ‰ 2 façons différentes pour représenter une
M:N qui nécessitent une table association association M:N :
dans le monde relationnel n une collection ou une map dans chacune

‰ On étudiera ensuite les autres associations


(ou dans une, selon la directionnalité) des
classes associées, qui référence les objets
associés
n une classe association qui représente une
instance de l’association
‰ Si l’association contient des propriétés, seule
la 2ème façon convient
R. Grin Mapping objet-relationnel page 29 R. Grin Mapping objet-relationnel page 30

5
Exemples de classes – solution 1 Solution 1 – variante avec Map
‰ class Employé { ‰ class Projet {
private Collection<Projet> projets; private Map<Integer, Employé> employés;
. . . . . .
} }
‰ class Projet { ‰ La clé peut, par exemple, représenter le
private Collection<Employé> employés; matricule d’un employé
. . .
} ‰ La variante avec map permet un accès rapide à
un des employés participant à un projet
‰ La classe Projet reste identique à la première
variante
R. Grin Mapping objet-relationnel page 31 R. Grin Mapping objet-relationnel page 32

Exemples de classes – solution 2 Association M:N - Relationnel


‰ class Employé { Employé ou/et Projet peuvent
. . . contenir une collection de ‰ Une association M:N est toujours traduite
} Participation pour permettre par une « table/relation association » (pour
‰ class Projet { la navigation
. . .
la suite on parlera de tables et pas de
} relations)
‰ class Participation { ‰ La clé primaire de cette table est le plus
private Employé employé; souvent formée des 2 clés des tables qui
private Projet projet; représentent les classes qui interviennent
. . . dans l’association
}

R. Grin Mapping objet-relationnel page 33 R. Grin Mapping objet-relationnel page 34

Exemple de traduction d’une Classe association (cas M:N)


association binaire M:N
‰ Si l'association a des propriétés, elles sont
‰ PARTICIPATION(matr, codeP) ajoutées dans la classe association et dans la
‰ En SQL : table association
create table participation (
matr integer references emp,
codeP varchar(2) references projet,
primary key(matr, codeP))

R. Grin Mapping objet-relationnel page 35 R. Grin Mapping objet-relationnel page 36

6
En objet
En relationnel
‰ class Participation {
private Employé employé;
private Projet projet; ‰ PARTICIPATION(matr, codeP, fonctionP)
private String fonction; ‰ En SQL :
. . . create table participation (
} matr integer references emp,
codeP varchar(2) references projet,
fonctionP varchar(15),
primary key(matr, codeP))

R. Grin Mapping objet-relationnel page 37 R. Grin Mapping objet-relationnel page 38

Association binaire dont une Exemple d’une association binaire


multiplicité maximum est 1 N:1 - Relationnel
(N:1 ou 1:1) - Relationnel
‰ EMP(matr,…, dept)
‰ On peut traduire les associations N:1 ou 1:1 par ‰ En SQL :
une table association, comme pour une create table emp (
matr integer primary key,
association M:N

‰ Mais le plus simple est d’ajouter la clé de l’autre dept smallint references dept)
classe dans la table qui traduit la classe placée
du côté opposé à la multiplicité 1
‰ La 1ère solution est plus souple mais plus
coûteuse (jointures)
R. Grin Mapping objet-relationnel page 39 R. Grin Mapping objet-relationnel page 40

Classe association (cas N:1 ou 1:1) Association de degré > 2 - Objet


‰ Si l'association est représentée par une classe ‰ Une association de degré > 2 peut être
association (rare), on peut ajouter les attributs représentée de plusieurs façons différentes
de la classe dans la table qui reçoit la clé de ‰ Le plus simple est sans doute de représenter
l'autre classe (ou dans la nouvelle table l’association par une « classe association » qui
association si on a choisi cette solution) contient des références vers les objets qui
participent à l’association
‰ Mais on peut aussi représenter une telle
association par des collections de classes qui
contiennent des collections ou des références
vers des classes qui contiennent des collections
R. Grin Mapping objet-relationnel page 41 R. Grin Mapping objet-relationnel page 42

7
Exemple d’association de degré > 2 Représentation par une classe
‰ Une réservation dans une compagnie ‰ class Reservation {
aérienne peut être considérée comme une private Vol vol;
private Passager passager;
association entre les avions, les passagers et private int siège;
les numéros de siège . . .
‰ En effet, un passager peut occuper plusieurs }
sièges (problème de santé par exemple)

R. Grin Mapping objet-relationnel page 43 R. Grin Mapping objet-relationnel page 44

Autre représentation Association de degré > 2


en relationnel
‰ class Vol {
private
‰ Dans le monde relationnel on crée une table
Collection<Reservation> résas;
. . . pour traduire l’association
} ‰ La clé primaire de cette table est le plus souvent
‰ class Reservation { formée d'un sous-ensemble des clés des tables
private Passager passager; qui traduisent les classes qui interviennent dans
private int siège; l’association
. . .
} ‰ Le sous-ensemble peut être strict si une
dépendance fonctionnelle existe entre ces clés

R. Grin Mapping objet-relationnel page 45 R. Grin Mapping objet-relationnel page 46

Exemple de traduction d’une Gestion des associations


association de degré > 2 bidirectionnelles
‰ Gérer une association est plus complexe dans
‰ RESERVATION(nVol, nSiège, codePassager, …) le monde objet que dans le monde relationnel,
‰ En SQL : surtout si elle est bidirectionnelle
create table reservation( ‰ Par exemple, si un employé change de
nvol varchar(10) references vol,
nsiege integer,
département, il suffit de changer le numéro de
codePassager varchar(10) département dans la ligne de l’employé
references passager, ‰ En objet, il faut en plus enlever l’employé de la
primary key(nVol, nSiege, codePassager), collection des employés du département et le
...)
rajouter dans la collection de son nouveau
département
R. Grin Mapping objet-relationnel page 47 R. Grin Mapping objet-relationnel page 48

8
Gestion automatique de Objet dépendant
l’ « autre bout » d’une association
‰ Certains framework (EJB 2 par exemple), ‰ Un objet dont le cycle de vie dépend du cycle
automatisent une partie de la gestion des de vie d’un autre objet auquel il est associé,
associations appelé objet propriétaire
‰ Aucun autre objet que le propriétaire ne doit
‰ Ainsi, si le champ « dept » d’un employé est
modifié, l’employé est passé avoir de référence directe vers un objet
automatiquement de la collection des dépendant
employés du département d’origine dans ‰ En ce cas, la suppression de l’objet
celle du nouveau département propriétaire doit déclencher la suppression
‰ D’autres frameworks comme Hibernate ou
des objets qui en dépendent (déclenchement
EJB 3/JPA préfèrent ne rien automatiser « en cascade »)
R. Grin Mapping objet-relationnel page 49 R. Grin Mapping objet-relationnel page 50

Exemple
‰ Une ligne de facture ne peut exister
qu’associée à une (en-tête de) facture
‰ Si on supprime une facture, toutes les lignes
de la facture doivent être supprimées Traduction de l’héritage
‰ Tous les outils de mapping, comme JPA,
offrent la possibilité d’automatiser les
suppressions en cascade d’objets
dépendants

R. Grin Mapping objet-relationnel page 51 R. Grin Mapping objet-relationnel page 52

Exemple Exemple
Classe
abstraite

‰ Pour fixer les idées, et ;-) pour reprendre des n Sportifs qui peuvent
dessins du très bon livre de Martin Fowler être des footballeurs
cité dans la bibliographie, on travaillera sur ou des joueurs de
l’exemple suivant tiré du monde anglophone : cricket
n des sportifs qui peuvent être des
footballeurs ou des joueurs de crickets
n parmi les joueurs de crickets, les joueurs
qui lancent la balle s’appellent les bowlers n Les joueurs de
cricket qui lancent la
‰ Pour en savoir plus sur le cricket :
balle : les bowlers
http://fr.wikipedia.org/wiki/Cricket

R. Grin Mapping objet-relationnel page 53 R. Grin Mapping objet-relationnel page 54

9
Plusieurs méthodes de traduction Accessibilité des variables (1)
‰ Représenter toutes les classes d’une ‰ Cette remarque est valable quelle que soit la
arborescence d’héritage par une seule table méthode de traduction de l’héritage et pour
relationnelle d’autre partie de ce cours
‰ Représenter chaque classe instanciable ‰ Les variables d’instance ne sont pas le plus
(concrète) par une table souvent accessibles de l’extérieur de la
‰ Représenter chaque classe, même les classes
classe
abstraites, par une table

R. Grin Mapping objet-relationnel page 55 R. Grin Mapping objet-relationnel page 56

Accessibilité des variables (2) Vocabulaire : « polymorphe »


‰ Association polymorphe : association
‰ Le code qui gère la persistance doit passer représentée par une référence vers une instance
par les accesseurs de ces variables, ou d’une classe ou des classes filles de cette classe
demander à chaque classe de participer à ‰ Par exemple, une société garde une référence
cette gestion de la persistance pour ses vers un sportif (d’un sport quelconque, footballeur
propres variables (cela dépend de la façon ou joueur de cricket) qu’elle sponsorise
dont est effectuée la persistance) ‰ Requête polymorphe : requête qui renvoie une
‰ Un moyen souvent utilisé par les outils de information conservée dans les instances d’une
mapping, est la réflexivité Java qui permet classe ou des classes filles de cette classe
d’outrepasser les restrictions d’accès ‰ Par exemple, requête qui renvoie les noms de
accolées aux variables d’instance tous les joueurs
R. Grin Mapping objet-relationnel page 57 R. Grin Mapping objet-relationnel page 58

Toutes les classes traduites


Avantages
par une seule table
‰ Souvent la solution la plus simple à mettre en
place
‰ C’est d’ailleurs la solution la plus
fréquemment choisie
‰ Permet les requêtes et associations
polymorphes

Pour différencier
les types de joueurs

R. Grin Mapping objet-relationnel page 59 R. Grin Mapping objet-relationnel page 60

10
Inconvénients Une table par classe

‰ Oblige à avoir de nombreuses colonnes qui


contiennent la valeur NULL
‰ On ne peut déclarer ces colonnes « NOT
NULL », même si cette contrainte est vraie
pour une des sous-classes

Colonne
optionnelle

R. Grin Mapping objet-relationnel page 61 R. Grin Mapping objet-relationnel page 62

Préservation de l’identité Préservation de l’identité


‰ Un objet a souvent ses attributs répartis sur ‰ Pour récupérer les informations sur une
plusieurs tables (celles qui correspondent aux instance d’une classe fille, il suffit de faire une
classes d’une même hiérarchie d’héritage) jointure sur ces clés primaires
‰ Son identité est alors préservée en donnant la
même clé primaire aux lignes qui correspondent
à l’objet dans les différentes tables
‰ Les clés primaires des tables correspondant aux
classes filles sont des clés étrangères vers la clé
primaire de la table correspondant à la classe
mère
R. Grin Mapping objet-relationnel page 63 R. Grin Mapping objet-relationnel page 64

Pour représenter un bowler Avantages


‰ Table Player : (Bill, bowler) ‰ Simple : bijection entre les classes et les
‰ Table Criketer : (Bill, 50) tables
‰ Table Bowler : (Bill, 48) ‰ Permet les requêtes et associations

‰ En réalité il faudrait utiliser une clé non


polymorphes
significative ; par exemple :
‰ Table Player : (158, Bill, bowler)
‰ Table Criketer : (158, 50)
‰ Table Bowler : (158, 48)

R. Grin Mapping objet-relationnel page 65 R. Grin Mapping objet-relationnel page 66

11
Inconvénient Une table par classe concrète

‰ Si la hiérarchie d’héritage est complexe


nécessite de nombreuses jointures pour
reconstituer les informations éparpillées dans
les tables
‰ D’où des instructions complexes, mais surtout
de mauvaises performances
‰ La colonne « type » de la table Players permet
de limiter un peu ce problème ; il est possible,
par exemple, de retrouver les noms des
footballers sans faire de jointure
R. Grin Mapping objet-relationnel page 67 R. Grin Mapping objet-relationnel page 68

Avantages Inconvénients (1)


‰ Ne peut traduire simplement les associations
‰ C’est la méthode la plus naturelle : une table
polymorphes
par type d’entité
‰ Par exemple, traduire une classe qui
‰ Pas de jointures pour retrouver les
référence un joueur d’un sport quelconque
informations
(joueur de football ou de cricket)
‰ En effet, aucune table relationnelle ne
correspond à un joueur d’un sport
quelconque et on ne peut donc imposer une
contrainte d’intégrité référentielle (clé
étrangère)

R. Grin Mapping objet-relationnel page 69 R. Grin Mapping objet-relationnel page 70

Solution Autre problème


‰ Aucune solution vraiment satisfaisante ‰ Dans le même ordre d’idée, il est difficile
‰ Des solutions partielles : d’interroger la base pour effectuer une requête
n ignorer la contrainte d’intégrité référentielle
polymorphe
‰ Par exemple, avoir le nom de tous les joueurs
n mettre plusieurs colonnes dans la table qui
référence, une pour chaque table concrète
référencée (mais ça sera difficile d’imposer
l’unicité de la référence ; sur l’exemple, ça
sera difficile d’imposer d’avoir une seule
référence vers un joueur)

R. Grin Mapping objet-relationnel page 71 R. Grin Mapping objet-relationnel page 72

12
Solution Inconvénients (2)
‰ Pas possible d’assurer simplement l’unicité
‰ On devra lancer plusieurs selects (un pour
des identificateurs pour tous les sportifs (ils
chaque sous-classe concrète) et utiliser une
sont répartis sur plusieurs tables distinctes)
union de ces selects
‰ Le select sera donc plus complexe et sans
doute moins performant

R. Grin Mapping objet-relationnel page 73 R. Grin Mapping objet-relationnel page 74

Conclusion : une solution à éviter Variantes


‰ Sauf pour des cas bien précis où le ‰ Dans une arborescence d’héritage ces
polymorphisme n’est pas important, il vaut stratégies peuvent être mélangées
mieux éviter cette solution ‰ On peut, par exemple, créer plusieurs tables
‰ D’ailleurs, la version actuelle de la pour plusieurs branches de l’arborescence
spécification EJB 3 n’impose pas aux d’héritage
serveurs d’application d’offrir cette possibilité ‰ Mais le risque est de retomber sur les
de traduction de l’héritage problèmes de la stratégie « une table par
classe concrète » avec les requêtes et les
associations polymorphes

R. Grin Mapping objet-relationnel page 75 R. Grin Mapping objet-relationnel page 76

Héritage multiple

‰ Dans les cas où l’héritage est traduit par des


tables séparées, l’identifiant dans les classes
descendantes est l’ensemble des identifiants des Récupération des objets
classes mères associés à un objet

R. Grin Mapping objet-relationnel page 77 R. Grin Mapping objet-relationnel page 78

13
2 stratégies pour les associations Une situation
‰ Lorsqu’un objet est créé à partir des données ‰ Recherche dans la base de données d’une
récupérées dans la base de données, 2 facture qui vérifie un certain critère
stratégies vis-à-vis des objets associés à cet ‰ Un objet de la classe Facture qui correspond
objet : à cette facture est créé
n récupération immédiate et création des ‰ Est-ce que les objets LigneFacture associés
objets associés à cette facture doivent aussi être créés ?
n les objets associés ne sont pas créés tout ‰ Et si la réponse est positive, faut-il créer aussi
de suite, mais seulement lorsque les objets Produit correspondants à chaque
l’application en a vraiment besoin ligne de facture ?
‰ Et si la réponse est positive, …
R. Grin Mapping objet-relationnel page 79 R. Grin Mapping objet-relationnel page 80

Le problème Récupération « à la demande »


‰ Le risque est de créer un très grand nombre ‰ La solution est le « lazy loading », mot à mot
d’objets, peut-être inutiles « récupération paresseuse », que l’on peut
‰ Par exemple, si on veut récupérer cette traduire par « récupération à la demande »
facture pour connaître seulement la date de ou « récupération retardée »
facturation, on voit que tous ces objets
associés sont totalement inutiles
‰ D’où de mauvaises performances, sans
raisons valables

R. Grin Mapping objet-relationnel page 81 R. Grin Mapping objet-relationnel page 82

Récupération « à la demande » Exemple (1)

‰ Quand un objet est créé à partir des données ‰ Le code recherche la facture de numéro 456
enregistrées dans la BD, les objets associés ‰ Un objet f de la classe Facture est créé
ne sont pas immédiatement créés ‰ Les objets correspondants aux lignes de la
‰ Ils sont remplacés par des objets « proxy » qui facture f sont remplacés par des objets d’une
ne contiennent que l’information nécessaire classe « proxy »
(clé primaire) pour retrouver les « vrais » ‰ Ces objets « proxy » ne contiennent que la
objets associés clé primaire des lignes de la facture dans la
‰ Les « vrais » objets ne seront créés par la table LIGNE_FACTURE
suite que si c’est vraiment indispensable

R. Grin Mapping objet-relationnel page 83 R. Grin Mapping objet-relationnel page 84

14
Exemple (2) Problème des « N + 1 selects »
‰ Si le programme contient ensuite le code ‰ Choisir une bonne stratégie pour récupérer
f.getLigne(i).getQuantite() les données n’est pas facile
‰ L’objet LigneFacture correspondant à la ‰ En effet, en voulant éviter de récupérer trop
ième ligne de facture est créé en allant de données on peut tomber sur le problème
chercher les informations sur la ligne dans la des « N + 1 selects »
base de données
‰ Le message « getQuantite() » lui est
envoyé

R. Grin Mapping objet-relationnel page 85 R. Grin Mapping objet-relationnel page 86

Un exemple de « N + 1 selects » Mauvaise solution


pour les « N + 1 selects »
‰ Récupérer les 5000 factures éditées après
une certaine date, avec une récupération « à ‰ Indiquer que la récupération pour cette
la demande » des lignes de la facture : association doit toujours être immédiate
‰ Les 5000 objets « Facture » sont d’abord (dans des fichiers de configuration par
récupérées (1 select), exemple) ne convient pas le plus souvent
‰ Puis, pour chacune des 5000 factures, les ‰ En effet, dans d’autres circonstances, on ne
lignes de facture associées sont récupérées souhaitera pas charger les lignes de factures
pour calculer le total (5000 selects) pour éviter de créer trop d’objets inutiles
‰ D’où un total de 5001 selects, alors qu’on
peut obtenir le résultat avec un seul select !
R. Grin Mapping objet-relationnel page 87 R. Grin Mapping objet-relationnel page 88

Solutions possibles (1) Solutions possibles (2)


‰ Lancer un ordre SQL ad hoc qui renvoie
uniquement ce qui est recherché ‰ Permettre de spécifier une stratégie spéciale
pour une requête particulière
‰ Exemple : pour trouver la facture qui a le plus
gros total, inutile de charger toutes les ‰ On peut alors indiquer que le mode de
factures et lignes de factures en mémoire récupération ne sera pas immédiat par
défaut, mais que ce mode devra être
‰ Le plus simple, mais ne convient pas si on
immédiat pour une requête particulière
veut des informations plus complexes sur les
objets associés ‰ Tous les outils de mapping le permettent

‰ Il faut cependant retenir que, lorsque c’est


possible, c’est souvent la meilleure solution
pour éviter la création de nombreux objets
R. Grin Mapping objet-relationnel page 89 R. Grin Mapping objet-relationnel page 90

15
Code avec JPA Code avec Hibernate
List results = session.createCriteria(Item.class)
String texteQuery = .add( Expression.eq("item.seller", user) )
.setFetchMode("bids", FetchMode.EAGER).list();
"select f from Facture f "
// évite duplication de résultats (due au outer join)
+ " join fetch f.lignes " Iterator items = new HashSet(results).iterator();
+ " where f.date > '1/1/06'"; List maxAmounts = new ArrayList();
Query query = em.createQuery(texteQuery); while (items.hasNext()) {
List<Facture> liste = Item item = (Item) items.next();
(List<Facture>)query.getResultList(); BigDecimal max = new BigDecimal("0");
System.out.println(liste.get(0).getLigne(0)); Iterator b = item.getBids().iterator();
while (b.hasNext()) {
Bid bid = (Bid) b.next();
Ne générera aucune if ( bid.getAmount().compareTo(max) == 1 )
max = bid.getAmount();
requête SQL }
maxAmounts.add(new MaxAmount(item.getId(), max));
}
R. Grin Mapping objet-relationnel page 91 R. Grin Mapping objet-relationnel page 92

Conclusion de cette partie du cours Bibliographie


‰ La correspondance entre le modèle objet et le ‰ Patterns of Enterprise Application
modèle relationnel n’est pas une tâche facile Architecture, de Martin Fowler, Addison
‰ Les outils et framework ORM (étudiés à la fin Wesley
de ce cours) réduisent grandement le code qui
permet cette correspondance et facilitent donc
les adaptations mutuelles des 2 modèles

R. Grin Mapping objet-relationnel page 93 R. Grin Mapping objet-relationnel page 94

16

Vous aimerez peut-être aussi