Vous êtes sur la page 1sur 65

Plan de cette partie

Prsentation de JPA
Entits persistantes
Gestionnaire de persistance
Complments sur les entits : identit,
associations, hritage
Langage dinterrogation
Modifications en volume
Exceptions

JPA

(Java Persistence API)


Universit de Nice - Sophia Antipolis
Version 1.6 20/11/07
Richard Grin

R. Grin

JPA

page 2

Plan de cette partie


Transaction
Concurrence
Entits dtaches
Fichiers de configuration XML
JPA et DAOs
Optimisation
Callbacks

R. Grin

JPA

Prsentation de JPA

page 3

R. Grin

EJB 3.0

JPA (Java persistence API) est la partie de la


spcification EJB 3.0 qui concerne la persistance
des composants dans une base de donnes
relationnelle
Peut s
sappliquer
appliquer sur toutes les applications Java,
mme celles qui sexcutent en dehors dun
serveur dapplications

Java EE 5 (Enterprise Edition) est une plateforme de dveloppement et un ensemble de


spcifications pour le dveloppement
dapplications dentreprises multi-tiers
EJB 3.0
3 0 fait partie de Java EE 5 ; ccest
est une
spcification rcente (mai 2006) dun cadre
(framework) pour lutilisation de composants
mtier rutilisables par des serveurs
dapplications Java

JPA

page 4

JPA

R. Grin

JPA

page 5

R. Grin

JPA

page 6

JPA

Solution ORM
Transparente : les classes des entits
persistantes sont indiffrentes au mcanisme de
persistance
Automatique : des appels simples de haut niveau
pour grer la persistance, tels que persist(objet)
pour rendre un objet persistant ; pas dappel de
bas niveau comme avec JDBC

R. Grin

JPA

page 7

JPA est un standard pour la persistance des


objets Java
Pour plus de prcisions, lire la spcification
ladresse
http://jcp org/aboutJava/communityprocess/pfd/js
http://jcp.org/aboutJava/communityprocess/pfd/js
r220/index.html

R. Grin

Avertissement
JPA est le plus souvent utilis dans le
contexte dun serveur dapplications
Ce cours tudie lutilisation de JPA par une
application autonome, en dehors de tout
serveur dapplications
d applications
Quelques informations sur lutilisation de JPA
avec un serveur dapplications sont donnes
dans ce cours mais un autre support
complmentaire est en prparation

JPA

page 9

Comme pour JDBC, lutilisation de JPA


ncessite un fournisseur de persistance qui
implmente les classes et mthodes de lAPI
GlassFish, est limplmentation de rfrence
de la spcification EJB 3
GlassFish utilise TopLink essentials comme
fournisseur de persistance pour JPA (produit
Oracle)
Dautres implmentations : TopLink,
Hibernate Entity Manager, BEA Kodo

R. Grin

Entits

JPA

page 10

Vocabulaire

Les classes dont les instances peuvent tre


persistantes sont appeles des entits dans la
spcification de JPA
Le dveloppeur indique quune classe est une
entit en lui associant lannotation
l annotation @Entity

page 8

Fournisseur de persistance

R. Grin

JPA

Dans la suite de ce cours et quand il ny aura


pas ambigut, entit dsignera soit une
classe entit, soit une instance de classe
entit, suivant le contexte

Ne pas oublier dimporter


javax.Persistence.Entity dans les
classes entits (idem pour toutes les
annotations)

R. Grin

JPA

page 11

R. Grin

JPA

page 12

Exemple dentit les champs

Les constructeurs
/**
* Constructeur sans paramtre
* obligatoire.
*/
public Departement() { }
public Departement(String nom,
String lieu) {
this.nom = nom;
this.lieu = lieu;
}

@Entity
public class Departement {
private int id;
private String nom;
private String lieu;
private Collection<Employe> employes =
new List<Employe>();

R. Grin

JPA

page 13

R. Grin

Exemple dentit lidentificateur

JPA

public String getNom() {


return nom;
}
public void setNom(String
p
(
g nom)
) {
this.nom = nom;
}

page 15

R. Grin

Lassociation inverse
dans la classe Employe

@OneToMany(mappedBy="dept")
public Collection<Employe> getEmployes() {
return employes;
}
public void setEmployes(Collection<Employe>
emps) {
this.employes = emps;
}

JPA

page 17

page 16

Les annotations @Entity (et toutes les autres


annotations JPA) peuvent tre remplaces ou/et
surcharges (les fichiers XML lemportent sur les
annotations) par des informations enregistres
dans un fichier de configuration XML
Exemple :

<table-generator name="empgen"
table="ID_GEN" pk-column-value="EmpId"/>

JPA

Fichiers de configuration XML

Exemple dentit une association

R. Grin

page 14

Exemple dentit une proprit

@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}

R. Grin

JPA

La suite nutilisera que les annotations

R. Grin

JPA

page 18

Exemple (dbut)

Configuration de la connexion
Il est ncessaire dindiquer au fournisseur de
persistance comment il peut se connecter
la base de donnes
Les informations doivent tre donnes dans
un fichier
f
persistence.xml situ
dans un
rpertoire META-INF dans le classpath

Ce fichier peut aussi comporter dautres


informations ; il est tudi en dtails dans la
suite du cours

R. Grin

JPA

page 19

<persistence
xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="Employes">
<class>jpa.Departement</class>
<class>jpa.Employe</class>
/
<properties>
<property name="toplink.jdbc.driver"
value="oracle.jdbc.OracleDriver"/>
<property name="toplink.jdbc.url"
value="jdbc:oracle:thin:@cl.truc.fr:1521:XE"/>
R. Grin

Exemple (fin)

JPA

page 20

Gestionnaire dentits

<property name="toplink.jdbc.user"
value="toto"/>
<property name="toplink.jdbc.password"
value="xxxxx"/>
</properties>
</persistence-unit>
</persistence>

R. Grin

JPA

page 21

Classe
javax.persistence.EntityManager

Le gestionnaire dentits (GE) est


linterlocuteur principal pour le dveloppeur
Il fournit les mthodes pour grer les entits :
les rendre persistantes, les supprimer de la
base de donnes, retrouver leurs valeurs
dans la base, etc.

R. Grin

Exemple de code (1)


EntityManagerFactory emf = Persistence.
createEntityManagerFactory("employes");
EntityManager em =
emf.createEntityManager();
EntityTransaction tx = em
em.getTransaction();
getTransaction();
tx.begin();
Dept dept = new Dept("Direction", "Nice");
em.persist(dept);
sera enregistr dans
la base de donnes
dept.setLieu("Paris");
tx.commit();
au moment du
commit page 23
R. Grin
JPA

JPA

page 22

Exemple de code (2)


String queryString =
"SELECT e FROM Employe e "
+ " WHERE e.poste = :poste";
Query query = em.createQuery(queryString);
query.setParameter("poste", "INGENIEUR");
Li t<Em l
List<Employe>
> li
liste
t =
query.getResultList();
for (Employe e : liste) {
System.out.println(e.getNom());
}
em.close();
emf.close()
R. Grin

JPA

page 24

Contexte de persistance
Remarque : le code prcdent devrait tre
inclus dans un bloc try finally (les
close finaux dans le finally), et pourrait
contenir ventuellement des blocs catch
pour attraper
tt
les
l exceptions
ti
(d
(des
RuntimeException) lances par les
mthodes de EntityManager
Ce bloc try finally a t omis pour ne
pas alourdir le code

R. Grin

JPA

page 25

La mthode persist(objet) de la classe


EntityManager rend persistant un objet

Lobjet est ajout un contexte de persistance


qui est gr par le GE
Toute modification apporte un objet du
contexte de persistance sera enregistre dans
la base de donnes
Lensemble des entits gres par un GE
sappelle un contexte de persistance

R. Grin

JPA

page 26

GE contexte de persistance
Dans le cadre dune application autonome, la
relation est simple : un GE possde un
contexte de persistance, qui nappartient qu
lui et il le garde pendant toute son existence
Lorsque
L
lle GE estt gr
par un serveur
dapplications, la relation est plus complexe ;
un contexte de persistance peut se propager
dun GE un autre et il peut tre ferm
automatiquement la fin de la transaction en
cours (voir support complmentaire)

R. Grin

JPA

page 27

Seules les entits peuvent tre


n renvoyes par une requte (Query)
n

passes en paramtre dune mthode dun


EntityManager ou dun Query

le but dune association


rfrences dans une requte JPQL
Une classe entit peut utiliser dautres classes
pour conserver des tats persistants
(MappedSuperclass ou Embedded tudies
plus loin)
n
n

R. Grin

JPA

R. Grin

JPA

page 28

Conditions pour les classes entits

Caractristiques

Entits

page 29

Elle doit possder un attribut qui reprsente la


cl primaire dans la BD (@Id)

Une classe entit doit avoir un constructeur


sans paramtre protected ou public
Elle ne doit pas tre final

Aucune mthode ou champ persistant ne doit


tre final

Si une instance peut tre passe par valeur en


paramtre dune mthode comme un objet
dtach, elle doit implmenter Serializable

R. Grin

JPA

page 30

Conditions pour les classes entits


Une classe entit ne doit pas tre une classe
interne
Une entit peut tre une classe abstraite mais
elle ne peut tre une interface

Convention de nommage JavaBean

R. Grin

JPA

page 31

R. Grin

Le fournisseur de persistance accdera la


valeur dune variable dinstance
n soit en accdant directement la variable
dinstance (par introspection)
n soit en passant par ses accesseurs (getter
ou setter)
Le type daccs est dtermin par
lemplacement des annotations (associes aux
variables dinstance ou aux getter)

JPA

Souvent une proprit correspond une


variable dinstance

page 33

Ils peuvent contenir dautres instructions que


le seul code li la valeur de la variable
sous-jacente
Ces instructions seront excutes par le
fournisseur de persistance
Si une exception est leve par un accesseur,
la transaction est invalide ; les exceptions
contrles sont enveloppes par une
PersistenceException (non contrle,
sous RuntimeException)

R. Grin

JPA

page 34

Choix du type daccs

Un champ dsigne une variable dinstance


JPA parle de proprit lorsque laccs se fait
en passant par les accesseurs (getter ou
setter)
Lorsque le type daccs est indiffrent, JPA
parle dattribut

JPA

page 32

Les accesseurs (setter et getter) doivent tre


protected ou public

Vocabulaire JPA

R. Grin

JPA

Accs par proprit

2 types daccs

R. Grin

Un JavaBean possde des proprits


Une proprit est reprsente par 2
accesseurs ( getter et setter ) qui
doivent suivre la convention de nommage
suivante :
si prop est le nom de la proprit, le getter
doit tre getProp (ou isProp si la proprit
est de type boolean) et le setter setProp

page 35

Le choix doit tre le mme pour toutes les


classes dune hirarchie dhritage (interdit de
mlanger les 2 faons)
En programmation objet il est conseill dutiliser
plutt les accesseurs que les accs directs aux
champs (meilleur contrle des valeurs) ; cest
aussi le cas avec JPA
Rappel : le choix est dtermin par
l'emplacement des annotations ; elles sont
associes soit aux accesseurs, soit aux
variables d'instance ; ne pas mlanger les 2 !

R. Grin

JPA

page 36

Attributs persistants

Cycle de vie dune instance dentit

Par dfaut, tous les attributs dune entit sont


persistants
Lannotation @Basic indique quun attribut
est persistant mais elle nest donc
indispensable que si on veut prciser des
informations sur cette persistance (par
exemple, une rcupration retarde)
Seuls les attributs dont la variable est
transient ou qui sont annots par
@Transient ne sont pas persistants

R. Grin

JPA

page 37

Linstance peut tre


n nouvelle (new) : elle est cre mais pas
associe un contexte de persistance
ng
gre p
par un g
gestionnaire de p
persistance ;
elle a une identit dans la base de donnes
(un objet peut devenir gr par la mthode
persist, ou merge dune entit dtache ;
un objet gr peut aussi provenir dune
requte faite par un gestionnaire dentits ou
dune navigation partir dun objet gr)

R. Grin

Cycle de vie dune instance dentit


dtache : elle a une identit dans la base
mais elle nest plus associe un contexte
de persistance (une entit peut, par
exemple, devenir dtache si le contexte
de persistance est vid ou si elle est
envoye dans une autre JVM par RMI)
n supprime : elle a une identit dans la
base ; elle est associe un contexte de
persistance et ce contexte doit la
supprimer de la base de donnes (passe
dans cet tat par la mthode remove)

JPA

Cycle de vie dune entit

R. Grin

JPA

page 39

Les tables de la base de donnes


Dans les cas simples, une table correspond
une classe
n le nom de la table est le nom de la classe
n les noms des colonnes correspondent
p
aux
noms des attributs persistants
Par exemple, les donnes de la classe
Departement sont enregistres dans la table
Departement (ou DEPARTEMENT) dont les
colonnes se nomment id, nom, lieu

R. Grin

JPA

page 41

page 38

refresh

Nouvelle

persist

clear

Gre

Dtache
merge

find
remove
Query
BD

Supprime
R. Grin

JPA

page 40

Configuration par exception


La configuration des classes entits suppose
des valeurs par dfaut
Il nest ncessaire dajouter des informations
de configuration que si ces valeurs par dfaut
ne conviennent pas
Par exemple, @Entity suppose que la table
qui contient les donnes des instances de la
classe a le mme nom que la classe

R. Grin

JPA

page 42

Nom de table

Nom de colonne

Pour donner la table un autre nom que le


non de la classe, il faut ajouter une
annotation @Table

Exemple :

Cette annotation peut aussi comporter des


attributs pour dfinir plus prcisment la
colonne
Exemple :

@Entity
@Table(name="AUTRENOM")
public class Classe {
...
}

R. Grin

JPA

Pour donner une colonne de la table un autre


nom que le nom de lattribut correspondant, il
faut ajouter une annotation @Column

@Column(name="AUTRENOM",
updatable=false, length=80)
public String getTruc() { ... }
page 43

R. Grin

Classe Embeddable
Les entits persistantes ne sont pas les seules
classes persistantes
Il existe aussi des classes insres ou
incorpores (embedded) dont les donnes
nont
n
ont pas didentit
d identit dans la BD mais sont
insres dans une des tables associes une
entit persistante
Elles peuvent tre annotes comme les entits
(avec @Column par exemple)
Par exemple, une classe Adresse dont les
valeurs sont insres dans la table Employe
JPA

page 45

Comme les entits, ces classes doivent avoir


un constructeur sans paramtre
Les types permis pour leurs attributs sont les
mmes que les types permis pour les
attributs des entits

R. Grin

Exemple
@Embeddable
public class Adresse {
private int numero;
private String rue;
private String ville;
. . .
}
@Entity
public class Employe {
@Embedded private Adresse adresse;
...
Rappel : mettre sur getAdresse()
si accs JPA
par proprit
R. Grin

page 44

Classe Embeddable

R. Grin

JPA

JPA

page 46

Restrictions
La version actuelle de JPA a plusieurs
restrictions (peut-tre enleves dans une
prochaine version) :
n une entit ne peut possder une collection
dobjets
d
objets insrs
n un objet insr ne peut rfrencer un autre
objet insr ni avoir une association avec
une entit
Un objet insr ne peut tre rfrenc par
plusieurs entits diffrentes

page 47

R. Grin

JPA

page 48

Classes insres partages

@AttributeOverride(s)

Une classe entit peut rfrencer plusieurs


instances dune mme classe insre
Par exemple, la classe Employe peut
comporter ladresse du domicile et ladresse
du travail des employs
En ce cas, les noms des colonnes dans la
table de lentit ne peuvent tre les mmes
pour chacune des utilisations
Lannotation @AttributeOverride peut
rsoudre le problme

R. Grin

JPA

page 49

Un champ annot par @Embedded peut tre


complt par une annotation
@AttributeOverride, ou plusieurs de ces
annotations insres dans une annotation
@AttributeOverrides

Ces annotations permettent dindiquer le nom


dune ou de plusieurs colonnes dans la table
de lentit
Elles peuvent aussi tre utilises si une
classe insre est rfrence par plusieurs
classes entits diffrentes

R. Grin

Exemple

JPA

page 51

Lannotation @Lob permet dindiquer quun


attribut est un LOB (Large OBject) : soit un
CLOB (Character LOB, tel un long rsum de
livre), soit un BLOB (Binary LOB, tel une
i
image
ou une squence

vido)
id )
Le fournisseur de persistance pourra ainsi
ventuellement traiter lattribut de faon
spciale (utilisation de flots dentres-sorties
par exemple)
Exemple : @Lob private byte[] image

R. Grin

Annotation pour numration

JPA

@Enumerated(EnumType.STRING)
private TypeEmploye typeEmploye;

R. Grin

R. Grin

page 53

page 52

Exemple

Une annotation spciale nest pas ncessaire


si un attribut est de type numration si
lnumration est sauvegarde dans la BD
sous la forme des numros des constantes
d l
de
lnumration
ti (d
(de 0 n))
Si on souhaite sauvegarder les constantes
sous la forme de la forme dune String qui
reprsente le nom de la valeur de
lnumration, il faut utiliser lannotation
@Enumerated

JPA

page 50

Annotation pour LOB

@Entity
public class Employe {
@Embedded
@AttributeOverrides({
@AttributeOverride(
name="ville",
column=@column(name="ville_travail")),
@AttributeOverride(...)
})
// Adresse du travail
private Adresse adresseTravail;
R. Grin

JPA

JPA

page 54

Types temporels

Annotation pour les types temporels

Lorsqu'une classe entit a un attribut de type


temporel (Calendar ou Date de
java.util), il est obligatoire d'indiquer de
quel type temporel est cet attribut par une
annotation @Temporal

3 types temporels dans lnumration


TemporalType : DATE, TIME, TIMESTAMP

Correspondent aux 3 types de SQL ou du


paquetage java.sql : Date, Time et
Timestamp

C tt indication
Cette
i di ti permettra
tt au ffournisseur
i
d
de
persistance de savoir comment dclarer la
colonne correspondante dans la base de
donnes : une date (un jour), un temps sur 24
heures (heures, minutes, secondes la
milliseconde prs) ou un timeStamp (date +
heure la microseconde prs)

R. Grin

JPA

page 55

R. Grin

Exemple

JPA

Il est possible de sauvegarder une entit sur


plusieurs tables
Voir @SecondaryTable dans la spcification
JPA
Cest surtout utile pour les cas o la base de
donnes existe dj et ne correspond pas
tout fait au modle objet

page 57

R. Grin

Schma relationnel

JPA

page 58

Exemple

Dans le cas o le schma relationnel est


construit automatiquement partir des
annotations, il est possible de prciser des
informations sur les tables gnres ou les
colonnes de ces tables
Par exemple, une contrainte d'unicit, ou "not
null", la longueur des colonnes de type
varchar, la prcision des nombres virgule,
ou mme le texte entier qui permet de dfinir
une colonne
Voir la spcification JPA pour plus de dtails

@Entity
@Table(name="PARTICIPATION2",
uniqueConstraints =
@UniqueConstraint(
columnNames
l
N
=
{"EMPLOYE_ID", "PROJET_ID"})
)
public class Participation {
...
}

R. Grin

R. Grin

JPA

page 56

Tables multiples

@Temporal(TemporalType.DATE)
private Calendar dateEmb;

R. Grin

JPA

page 59

JPA

page 60

10

Types persistants
Les champs des entits peuvent tre d peu
prs nimporte quel type :
Types primitifs
Types String, BigInteger, BigDecimal, classes
enveloppes
l
d
de type primitifs,
i i if D
Date (d
(des
paquetages util et sql), Calendar, Time,
Timestamp, et plus gnralement Serializable
Enumrations
Entits et collections dentits, classes
Embeddable

R. Grin

JPA

page 61

Gestionnaire dentits
(Entity Manager),
) GE

R. Grin

Principe de base

page 62

Unit de persistance

La persistance des entits nest pas


transparente
Une instance dentit ne devient persistante
que lorsque lapplication appelle la mthode
approprie
i d
du gestionnaire
ti
i dentit
d tit (persist
(
i
ou merge)

JPA

Cest une configuration nomme qui contient les


informations ncessaires lutilisation dune base
de donnes
Elle est associe un ensemble de classes
entits

Cette conception a t voulue par les


concepteurs de lAPI par souci de flexibilit et
pour permettre un contrle fin sur la
persistance des entits

R. Grin

JPA

page 63

Configuration dune unit


de persistance

page 64

Les entits gres par un gestionnaire dentits


forment un contexte de persistance
Quand une entit est incluse dans un contexte de
persistance (persist ou merge), ltat de lentit
est automatiquement sauvegard dans la base
au moment du commit de la transaction
Proprit importante : dans un contexte de
persistance il nexiste pas 2 entits diffrentes qui
reprsentent des donnes identiques dans la
base

Les informations sur une unit de persistance


sont donnes dans un fichier
persistence.xml situ dans un sousrpertoire META
META-INF
INF d
dun
un des rpertoires du
classpath
Voir section Configuration dune unit de
persistance dans la suite du cours

JPA

JPA

Contexte de persistance (1)

R. Grin

R. Grin

page 65

R. Grin

JPA

page 66

11

Contexte de persistance (2)

Contexte de persistance - cache

Un contexte de persistance ne peut appartenir


qu une seule unit de persistance
Une unit de persistance peut contenir plusieurs
contextes de persistance
Cest
C
lla responsabilit
bili d
de llapplication
li i d
de
sassurer quune entit nappartient qu un seul
contexte de persistance (afin que 2 entits de 2
contextes de persistance diffrents ne puissent
correspondre des donnes identiques dans la
base de donnes)

R. Grin

JPA

page 67

Le contexte de persistance joue le rle de


cache et vite ainsi des accs la base
Si le code veut rcuprer des donnes (par
un find ou un query) qui correspondent
une entit du contexte, ce sont les donnes
du cache qui sont renvoyes
Important : si les donnes de la base ont t
modifies (et valides) en parallle dans la
base, les donnes rcupres ne tiennent
pas compte de ces modifications

R. Grin

Ce fonctionnement peut tre bnfique :


meilleures performances, isolation lecture
rptable sans modifier les paramtres de
la base de donnes
Sil est au contraire malvenu, il est possible
de rcuprer des modifications effectues en
parallle sur les donnes dune entit en
utilisation la mthode refresh de
EntityManager

R. Grin

R. Grin

JPA

page 69

Elle reprsente un GE
Implmentation fournie par le fournisseur de
persistance

Types de GE
GE gr par le container (uniquement
disponible dans un serveur dapplications ; pas
tudi dans ce cours) ; le contexte de
persistance peut tre limit une seule
transaction
GE gr par lapplication (seul type disponible
en dehors dun serveur dapplications) ; le
contexte de persistance reste attach au GE
pendant toute son existence

JPA

JPA

page 70

Cycle de vie dun GE

R. Grin

page 68

Interface EntityManager

Contexte de persistance - cache

JPA

page 71

En dehors dun serveur dapplications, cest


lapplication qui dcide de la dure de vie
dun GE
La mthode createEntityManager() de
la classe EntityManagerFactory cr un
GE
Le GE est supprim avec la mthode
close() de la classe EntityManager ; il
ne sera plus possible de lutiliser ensuite

R. Grin

JPA

page 72

12

Fabrique de GE

A savoir

La classe Persistence permet dobtenir une


fabrique de gestionnaire dentits par la
mthode createEntityManagerFactory
2 variantes surcharges de cette mthode :
n 1 seul p
paramtre q
qui donne le nom de lunit
de persistance (dfinie dans le fichier
persistence.xml)
me paramtre de type Map qui contient
n Un 2
des valeurs qui vont craser les proprits
par dfaut contenues dans persistence.xml

R. Grin

JPA

page 73

Une EntityManagerFactory est threadsafe


Un EntityManager ne lest pas
Crer une EntityManagerFactory est une
opration lourde
Crer un EntityManager est une opration
lgre
Il est donc intressant de conserver une
EntityManagerFactory entre 2 utilisations

R. Grin

JPA

page 74

Mthodes de EntityManager

Mauvaise configuration

Si elle rencontre une mauvaise configuration


(dans le fichier persistence.xml, dans les
annotations, y compris dans la syntaxe des
requtes nommes ou dans les fichiers XML)
l mthode
la
th d
Persistence.createEntityManagerFactory

ne se terminera pas correctement et lancera


une exception

R. Grin

JPA

page 75

void persist(Object entit)


<T> T merge(T entit)
void remove(Object entit)
<T> T find(Class<T> classeEntit,
Object clPrimaire)
<T> T getReference(Class<T>
classeEntit, Object clPrimaire)
void flush()
void setFlushMode(FlushModeType
flushMode)

R. Grin

Mthodes de EntityManager

R. Grin

R. Grin

page 77

page 76

Mthodes de EntityManager

void lock(Object entit,


LockModeType lockMode)
void refresh(Object entit)
void clear()
boolean contains(Object entit)
Query createQuery(String requte)
Query createNamedQuery(String nom)

JPA

JPA

Query createNativeQuery(String
requte)
Query createNativeQuery(String
requte, Class classeRsultat)
void joinTransaction()
void close()
boolean isOpen()
EntityTransaction getTransaction()

JPA

page 78

13

flush

flush

Toutes les modifications effectues sur les


entits du contexte de persistance gres par
le GE sont enregistres dans la BD lors dun
flush du GE
Au moment du flush, le GE tudie ce quil doit
faire pour chacune des entits quil gre et il
lance les commandes SQL adaptes pour
modifier la base de donnes (INSERT,
UPDATE ou DELETE)

R. Grin

R. Grin

JPA

page 79

Un flush est automatiquement effectu au


moins chaque commit de la transaction en
cours
Une exception
TransactionRequiredException est
leve si la mthode flush est lance en
dehors dune transaction

Soit X une des entits gre, avec une


association de X vers une entit Y
Si cette association est note avec
cascade=persist ou cascade=all, Y est
elle aussi flushe
Sinon, si Y est new ou removed, une
exception IllegalStateException sera
leve et la transaction est invalide (rollback)
Sinon, si Y est dtache et X possde
lassociation, Y est flushe ; si Y est la
propritaire, le comportement est indfini

R. Grin

R. Grin

page 81

Normalement (mode FlushMode.AUTO) un


flush des entits concernes par une requte
est effectu avant la requte pour que le
rsultat tienne compte des modifications
effectues en mmoire sur ces entits
Il est possible d'viter
d viter ce flush avec la
mthode setFlushMode :
em.setFlushMode(FlushMode.COMMIT);
En ce cas, un flush ne sera lanc qu'avant un
commit
Il est possible de modifier ce mode pour une
seule requte (voir Query)

Une entit nouvelle devient une entit


gre
Ltat de lentit sera sauvegard dans la BD
au prochain flush ou commit
Aucune instruction ne sera ncessaire pour
faire enregistrer au moment du commit dans
la base de donnes les modifications
effectues sur lentit par lapplication ; en
effet le GE conserve toutes les informations
ncessaires sur les entits quil gre

JPA

JPA

page 82

persist(A)

persist

R. Grin

page 80

Mode de flush

flush

JPA

JPA

page 83

Si A est nouvelle, elle devient gre


Si A tait dj gre, persist est ignore
mais lopration persist cascade sur les
entits associes si lassociation a lattribut
yp
CascadeType.PERSIST

Si A est supprime (a t passe en


paramtre remove), elle devient gre

Si A est dtache, une


IllegalArgumentException est lance

R. Grin

JPA

page 84

14

remove

remove(A)

Une entit gre devient supprime


Les donnes correspondantes seront
supprimes de la BD

Si A est gre, elle devient supprime


(les donnes correspondantes de la base
seront supprimes de la base au moment du
flush du contexte de persistance)
Ignore si A est nouvelle ou supprime
Si A est dtache, une
IllegalArgumentException est lance

R. Grin

JPA

page 85

Ne peut tre utilis que dans le contexte


dune transaction

R. Grin

refresh

Les donnes de la BD sont copies dans


lentit
Utiliser cette mthode pour sassurer que
lentit a les mmes donnes que la BD
Peut tre utile pour les transactions longues

JPA

page 87

Ignore si A est nouvelle ou supprime


Si A est nouvelle, lopration cascade sur
les associations qui ont lattribut
CascadeType.REFRESH
Si A est dtache, une
IllegalArgumentException est lance

R. Grin

find

JPA

page 88

lock(A)

La recherche est polymorphe : l'entit


rcupre peut tre de la classe passe en
paramtre ou d'une sous-classe (renvoie null
si aucune entit na lidentificateur pass en
paramtre)
Exemple :
Article p =
em.find(Article.class, 128);
peut renvoyer un article de n'importe quelle
sous-classe de Article (Stylo, Ramette,)

R. Grin

R. Grin

JPA

page 86

refresh(A)

Le GE peut synchroniser avec la BD une


entit quil gre en rafraichissant son tat en
mmoire avec les donnes actuellement
dans la BD :
em.refresh(entite);
(
);

R. Grin

JPA

page 89

Le fournisseur de persistance gre les accs


concurrents aux donnes de la BD
reprsentes par les entits avec une
stratgie optimiste
lock permet de modifier
f la manire
de grer

les accs concurrents une entit A


Sera tudi plus loin dans la section sur la
concurrence

JPA

page 90

15

Entit dtache (1)

Entit dtache (2)

Une application distribue sur plusieurs


ordinateurs peut utiliser avec profit des
entits dtaches
Une entit gre par un GE peut tre
dtache de son contexte de persistance ;
par exemple, si le GE est ferm ou si lentit
est transfre sur une autre machine en
dehors de la porte du GE

R. Grin

R. Grin

JPA

page 91

Une entit dtache peut tre modifie


Pour que ces modifications soient
enregistres dans la BD, il est ncessaire de
rattacher lentit un GE (pas
ncessairement celui do elle a t
dtache) par la mthode merge

merge(A)
Renvoie une entit gre A ; plusieurs cas :
Si A est une entit dtache, son tat est copi
dans une entit gre A qui a la mme identit
que A (si A nexiste pas dj, il est cr)
Si A est nouvelle,
nouvelle une nouvelle entit gre A'
A
est cr et ltat de A est copi dans A (un id
automatique ne sera mis dans A quau commit)
Si A est dj gre, merge renvoie A ; en plus
merge cascade pour tous les associations
avec lattribut CascadeType.MERGE

JPA

page 92

merge(A)

R. Grin

JPA

page 93

Si A a t marque supprime par la


mthode remove, une
IllegalArgumentException est lance

R. Grin

JPA

page 94

En dehors dune transaction (1)

merge(A)
Elle retourne une entit gre qui a la mme
identit dans la BD que lentit passe en
paramtre, mais a nest pas le mme objet
((sauf si A tait dj
j g
gre))
Aprs un merge, lapplication devra donc, sauf
cas exceptionnel, ne plus utiliser lobjet A ; on
pourra avoir ce type de code :
a = em.merge(a);
lobjet anciennement point par a ne sera plus
rfrenc

Les mthodes suivantes (read only) peuvent


tre lances en dehors dune transaction :
find, getReference, refresh et requtes
(query)
Les mthodes persist, remove, merge
peuvent tre excutes en dehors dune
d une
transaction ; les modifications quelles ont
provoques seront enregistres par un flush
ds quune transaction est active
Les mthodes flush, lock et modifications
de masse (executeUpdate) ne peuvent tre
lances en dehors dune transaction

R. Grin

R. Grin

Attention, la mthode merge nattache pas A

JPA

page 95

JPA

page 96

16

En dehors dune transaction (2)


En fait, certains SGBD se mettent en mode
autocommit lorsque des modifications sont
effectues sur des entits gres en dehors
dune transaction, ce qui peut poser de srieux
problmes (en cas de rollback de la
transaction par lapplication, ces modifications
ne seront pas invalides)
Il est donc conseill de neffectuer les
modifications sur les entits gres que dans
le contexte dune transaction, ou au moins de
tester le comportement du SGBD

Transaction non termine

R. Grin

JPA

page 97

Il ne faut jamais oublier de terminer une


transaction par commit() ou rollback()
car le rsultat dpend du fournisseur de
persistance et du SGBD

R. Grin

JPA

page 98

Cl primaire
Une entit doit avoir un attribut qui correspond
la cl primaire dans la table associe
La valeur de cet attribut ne doit jamais tre
modifie par lapplication ds que lentit
correspond une ligne de la base
Cet attribut doit tre dfini dans lentit racine
dune hirarchie dhritage (uniquement cet
endroit dans toute la hirarchie dhritage)
Une entit peut avoir une cl primaire
composite (pas recommand)

Identit des entits

R. Grin

JPA

page 99

R. Grin

Lattribut cl primaire est dsign par


lannotation @Id

Pour une cl composite on utilise


@EmbeddedId ou @IdClass

R. Grin

JPA

page 100

Type de la cl primaire

Annotation

JPA

page 101

Le type de la cl primaire (ou des champs


dune cl primaire compose) doit tre un des
types suivants :
n type primitif Java
n classe qui enveloppe un type primitif
n java.lang.String
n java.util.Date
n java.sql.Date

Ne pas utiliser les types numriques non


entiers

R. Grin

JPA

page 102

17

Types de gnration

Gnration automatique de cl
Si la cl est de type numrique entier,
lannotation @GeneratedValue indique que
la cl primaire sera gnre automatiquement
par le SGBD
Cette annotation peut avoir un attribut
strategy qui indique comment la cl sera
gnre (il prend ses valeurs dans
lnumration GeneratorType)

R. Grin

JPA

page 103

AUTO : le type de gnration est choisi par le


fournisseur de persistance, selon le SGBD
(squence, table,) ; valeur par dfaut
SEQUENCE : utilise une squence est utilise
IDENTITY : une colonne de type IDENTITY
est utilise
TABLE : une table qui contient la prochaine
valeur de lidentificateur est utilise
On peut aussi prciser le nom de la squence
ou de la table avec lattribut generator

R. Grin

Prcisions sur la gnration

JPA

Exemple

Les annotations @SequenceGenerator et


@TableGenerator permettent de donner
plus de prcisions sur la squence ou la table
qui va permettre de gnrer la cl
Par exemple @SequenceGenerator permet
de prciser la valeur initiale ou le nombre de
cls rcupres chaque appel de la
squence
Voir la spcification de JPA pour plus de
prcisions

@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "EMP_SEQ")
public
bli l
long getId()
tId() {
return id;
}

R. Grin

R. Grin

JPA

page 105

Si une squence utilise par JPA est cre


en dehors de JPA, il faut que la valeur de
pr-allocation de JPA (gale 50 par dfaut)
corresponde la valeur dincrmentation de
l squence
la

; on aura alors
l
souventt ce ttype
dannotation :
@SequenceGenerator(
name="seq3", sequenceName="seq3",
initialValue="125, allocationSize="20")

R. Grin

JPA

page 107

JPA

page 106

persist et id automatique

Valeur d'incrment d'une squence

page 104

La spcification nimpose rien sur le moment


o la valeur de lidentificateur est mise dans
lobjet gr
La seule assurance est quaprs un flush
dans la base de donnes (donc un commit)
lidentificateur aura dj reu sa valeur
Avec TopLink et Oracle (et peut-tre avec
dautres produits), la valeur de lidentificateur
est mise ds lappel de persist, sans
attendre le commit, mais il est risqu pour la
portabilit de lutiliser

R. Grin

JPA

page 108

18

Cl composite

Classe pour la cl composite

Pas recommand, mais une cl primaire peut


tre compose de plusieurs colonnes
Peut arriver quand la BD existe dj ou
quand la classe correspond une table
association (association M:N)
2 possibilits :
n @IdClass
n @EmbeddedId et @Embeddable

R. Grin

R. Grin

JPA

page 109

@EmbeddedId correspond au cas o la


classe entit comprend un seul attribut
annot @EmbeddedId

La classe cl primaire est annot par


@Embeddable

Le type daccs (par champs ou proprits)


de la classe embeddable doit tre le
mme que celui de lentit dont la cl
primaire est dfinie
JPA

JPA

page 111

@Entity
public class Employe {
@EmbeddedId
private EmployePK employePK;
...
}
@Embeddable
public class EmployePK {
private String nom;
private Date dateNaissance;
...
}
R. Grin

JPA

page 112

Exemple avec @IdClass

@IdClass
@IdClass correspond au cas o la classe
entit comprend plusieurs attributs annots
par @Id
La classe entit est annote par @IdClass
qui prend en paramtre le nom de la classe
cl primaire
La classe cl primaire nest pas annote ; ses
attributs ont les mmes noms et mmes
types que les attributs annots @Id dans la
classe entit

@Entity
@IdClass(EmployePK)
public class Employe {
@Id private String nom;
@Id Date dateNaissance;
...
}
public class EmployePK {
private String nom;
private Date dateNaissance;
...
}

R. Grin

R. Grin

JPA

page 110

Exemple avec @EmbeddedId

@EmbeddedId

R. Grin

Dans les 2 cas, la cl primaire doit tre


reprsente par une classe Java dont les
attributs correspondent aux composants de la
cl primaire
La classe doit tre
public, possder

un
constructeur sans paramtre, tre srialisable
et redfinir equals et hashcode

page 113

JPA

page 114

19

Quelle solution choisir ?


@IdClass existe pour assurer une
compatibilit avec la spcification EJB 2.0
Quand c'est possible il vaut mieux utiliser
@EmbeddedId
@IdClass a aussi son utilit, par exemple,
pour les associations M:N si on veut que la
cl primaire de la table association soit
compose des cls trangres vers les tables
qui sont associes (voir section sur les
associations)

R. Grin

JPA

page 115

Associations

R. Grin

Gnralits

JPA

Exemple

Une association peut tre uni ou


bidirectionnelle
Elle peut tre de type 1:1, 1:N, N:1 ou M:N
Les associations doivent tre indiques
q
p
par
une annotation sur la proprit
correspondante, pour que JPA puisse les
grer correctement

@ManyToOne
public Departement getDepartement() {
...
}

R. Grin

R. Grin

JPA

page 117

Reprsentation des associations


1:N et M:N

Elles sont reprsentes par des collections ou


maps qui doivent tre dclares par un des
types interface suivants (de java.util) :
n Collection
n Set
n List
n Map

Les variantes gnriques sont conseilles ;


par exemple Collection<Employe>

R. Grin

JPA

page 116

page 119

JPA

page 118

Types utiliser
Le plus souvent Collection sera utilis
Set peut tre utile pour liminer les doublons
Les types concrets, tels que HashSet ou
ArrayList, ne peuvent tre utiliss que pour
des entits nouvelles ; ds que lentit est
gre, les types interfaces doivent tre utiliss
(ce qui permet au fournisseur de persistance
dutiliser son propre type concret)
List peut tre utilis pour conserver un ordre
mais ncessite quelques prcautions

R. Grin

JPA

page 120

20

@OrderBy

Ordre dans les collections

Cette annotation indique dans quel ordre sont


rcupres les entits associes
Il faut prciser un ou plusieurs attributs qui
dterminent l'ordre
Chaque attribut peut tre prcis par ASC ou
DESC (ordre ascendant ou descendant);
ASC par dfaut
Les diffrents attributs sont spars par une
virgule
Si aucun attribut n'est prcis, l'ordre sera
celui de la cl primaire

Lordre dune liste n'est pas ncessairement


prserv dans la base de donnes
De plus, lordre en mmoire doit tre
maintenu par le code (pas automatique)
Tout ce quon peut esprer est de rcuprer
les entits associes dans la liste avec un
certain ordre lors de la rcupration dans la
base, en utilisant lannotation @OrderBy

R. Grin

JPA

page 121

R. Grin

Exemples

Le dveloppeur est responsable de la gestion


correcte des 2 bouts de lassociation
Par exemple, si un employ change de
dpartement, les collections des employs
des dpartements concerns doivent tre
modifies
Un des 2 bouts est dit propritaire de
lassociation

@OrderBy("poste DESC, nomEmploye ASC")

JPA

page 123

R. Grin

Bout propritaire
Pour les associations autres que M:N ce bout
correspond la table qui contient la cl
trangre qui traduit lassociation
Pour les associations M:N le dveloppeur
peut choisir arbitrairement le bout propritaire
Lautre bout (non propritaire) est qualifi par
lattribut mappedBy qui donne le nom de
lattribut dans le bout propritaire qui
correspond la mme association
JPA

JPA

page 124

Exemple

R. Grin

page 122

Associations bidirectionnelles

@Entity
public class Departement {
...
@OneToMany(mappedBy="departement")
@O d B ("
@OrderBy("nomEmploye")
E l
")
public List<Employe> getEmployes() {
...

R. Grin

JPA

page 125

Dans la classe Employe :


@ManyToOne
public Departement getDepartement() {
return departement;
}

Dans la classe Departement :


@OneToMany(mappedBy="departement")
public Collection<Employe> getEmployes() {
return employes;
}

R. Grin

JPA

page 126

21

Mthode de gestion de lassociation


Pour faciliter la gestion des 2 bouts d'une
association le code peut comporter une
mthode qui effectue tout le travail
En particulier, dans les associations 1-N, le
bout 1 peut comporter ce genre de
mthode (dans la classe Departement dune
association dpartement-employ) :

public void ajouterEmploye(Employe e) {


this.employes.add(e);
employe.setDept(this);
}
R. Grin

JPA

page 127

Annotation @JoinColumn
Cette annotation donne le nom de la colonne
cl trangre qui reprsente l'association
dans le modle relationnel
Elle doit tre mise du ct propritaire (celui
qui contient la cl trangre)
Sans cette annotation, le nom est dfini par
dfaut :
<entit_but>_<cl_primaire_entit_but>

R. Grin

Exemple
Pour l'association qui dtermine le
dpartement d'un employ
Par dfaut, la colonne cl trangre place
dans la table EMPLOYE s'appellera
Departement ID
Departement_ID
Pour changer ce nom (dans la classe
Employe) :
@ManyToOne
@JoinColumn(name="DEPT_ID")
public Departement getDepartement() {
R. Grin

JPA

page 129

Lannotation @JoinColumns permet


dindiquer le nom des colonnes qui
constituent la cl trangre dans le cas o il y
en a plusieurs (si la cl primaire rfrence
contient
ti t plusieurs
l i
colonnes)
l
)
En ce cas, les annotations @JoinColumn
doivent ncessairement comporter un attribut
referencedColumnName pour indiquer
quelle colonne est rfrence (parmi les
colonnes de la cl primaire rfrence)

R. Grin

Exemple

JPA

page 130

Persistance par transitivit

@JoinColumns({
@JoinColumn(name="n1",
referencedColumnName="c1"),
@JoinColumn(name="n2",
referencedColumnName="c2")
f
dC l
N
" 2")
})

R. Grin

R. Grin

JPA

page 128

Annotation @JoinColumns

JPA

page 131

Un service de persistance implmente la


persistance par transitivit (reachability) si
une instance devient automatiquement
persistante lorsquelle est rfrence par une
i t
instance
dj persistante
i t t
Cest un comportement logique : un objet
nest pas vraiment persistant si une partie
des valeurs de ses proprits nest pas
persistante
JPA

page 132

22

Pas si simple

Le choix de JPA

Maintenir une cohrence automatique des


valeurs persistantes nest pas si simple
Par exemple, si un objet devient non
persistant, faut-il aussi rendre non persistants
tous objets
j
q
qu'il a rendu p
persistants p
par
transitivit ?
De plus, le service de persistance doit alors
examiner toutes les rfrences des objets qui
sont rendus persistants, et ce de faon
rcursive, ce qui peut nuire grandement aux
performances

R. Grin

JPA

page 133

Par dfaut, JPA neffectue pas de persistance


par transitivit automatique : rendre
persistant un objet ne suffit pas rendre
automatiquement et immdiatement
persistants
i t t tous
t
les
l objets
bj t quil
il rfrence
f
Comme la cohrence n'est pas gre
automatiquement, c'est le code de
lapplication qui se doit de conserver cette
cohrence, au moins au moment du commit

R. Grin

Cohrence des donnes


Si le code a mal gr cette cohrence, une
exception est lance
Par exemple, si un dpartement est rendu
persistant alors que la collection des
employs du dpartement contient des
employs non persistants, une
IllegalStateException va tre lance
au moment du commit, et la transaction va
tre invalide (rollback)

JPA

page 135

Afin de faciliter le maintien de cette


cohrence, il est possible dindiquer JPA
que les objets associs un objet persistant
doivent tre automatiquement rendus
persistants
i t t
Pour cela il suffit dajouter un attribut
cascade dans les informations de
mapping de lassociation

R. Grin

Attribut cascade

JPA

page 136

Exemples

Les annotations qui dcrivent les associations


entre objets peuvent avoir un attribut cascade
pour indiquer que certaines oprations du GE
doivent tre appliques aux objets associs
Ces oprations sont PERSIST, REMOVE,
REFRESH et MERGE ; ALL correspond toutes
ces oprations
Par dfaut, aucune opration nest applique
transitivement

R. Grin

R. Grin

JPA

page 134

Persistance automatique

R. Grin

JPA

page 137

@OneToMany(
cascade=CascadeType.PERSIST)
@OneToMany(
cascade={CascadeType.PERSIST,
CascadeType.MERGE})
yp

JPA

page 138

23

Association 1:1 sur les cls

Association 1:1

Annotation @OneToOne

@OneToOne
public Adresse getAdresse() {

R. Grin

JPA

2 classes peuvent tre relies par leur


identificateur : 2 entits sont associes ssi elles
ont les mmes cls
Lannotation @PrimaryKeyJoinColumn doit
alors tre utilise pour indiquer au fournisseur
de persistance quil ne faut pas utiliser une cl
trangre part pour reprsenter lassociation
Attention, cest au dveloppeur de sassurer que
les entits associes ont bien les mmes cls

Reprsente par une cl trangre ajoute


dans la table qui correspond au ct
propritaire
Exemple :

page 139

R. Grin

Exemple

JPA

page 140

Associations 1:N et N:1

@OneToOne
@PrimaryKeyJoinColumn
private Employe employe

R. Grin

JPA

page 141

Annotations @OneToMany et @ManyToOne

Reprsente par une cl trangre dans la


table qui correspond au ct propritaire
(obligatoirement le ct Many )

R. Grin

Exemple

JPA

page 142

Cas particulier

class Employe {
...
@ManyToOne
public Departement getDepartement() {
...
}
}
class Departement {
...
@OneToMany(mappedBy="departement")
public List<Employe> getEmployes() {
...
}
}
R. Grin

JPA

page 143

Une association unidirectionnelle 1:N est


traduite pas une table association
Si on traduisait lassociation par une cl
trangre dans la table du ct N , a
poserait un problme pour rendre une
instance du ct N persistante : que
mettre dans la cl primaire ? Avec la table
association, cest seulement quand linstance
du ct 1 sera rendu persistant quune
ligne sera ajoute dans la table association

R. Grin

JPA

page 144

24

1:N unidirectionnelle

Association M:N

public class Dept {


...
@OneToMany
@JoinTable(name="DEPT_EMP",
j i C l
joinColumns=@JoinColumn(name="DEPT_ID"),
@J i C l
(
"DEPT ID")
inverseJoinColumns=
@JoinColumn(name="EMP_ID"))
private Collection<Employe> employes;
...
}
R. Grin

JPA

page 145

Annotation @ManyToMany

Reprsente par une table association

R. Grin

Association M:N (1)

JPA

page 146

Association M:N (2)

Les valeurs par dfaut :


n le nom de la table association est la
concatnation des 2 tables, spares par
_
n les
l noms d
des colonnes
l
cls
l
trangres

sont
les concatnations de la table rfrence,
de _ et de la colonne Id de la table
rfrence

R. Grin

JPA

page 147

Si les valeurs par dfaut ne conviennent pas,


le ct propritaire doit comporter une
annotation @JoinTable

Lautre ct doit toujours comporter lattribut


mappedBy
dB

R. Grin

JPA

page 148

Exemple (classe Employe)

@JoinTable
Donne des informations sur la table
association qui va reprsenter lassociation
Attribut name donne le nom de la table
Attribut joinColumns donne les noms des
colonnes de la table qui rfrencent les cls
primaires du ct propritaire de lassociation
Attribut inverseJoinColumns donne les
noms des colonnes de la table qui
rfrencent les cls primaires du ct qui
nest pas propritaire de lassociation

@ManyToMany
@JoinTable(
name="EMP_PROJET"
joinColumns=@JoinColumn(name="matr")
i
inverseJoinColumns=
J i C l
@JoinColumn(name="codeProjet")
)
public Collection<Projet> getProjets() {

R. Grin

R. Grin

JPA

page 149

JPA

page 150

25

Association M:N avec information


porte par l'association

Exemple (classe Projet)


@ManyToMany(mappedBy="projets")
public Collection<Employe> getEmps() {

R. Grin

JPA

Une association M:N peut porter une


information
Exemple :
Association entre les employs et les projets
Un employ a une (et une seule) fonction
dans chaque projet auquel il participe
En ce cas, il n'est pas possible de traduire
l'association en ajoutant 2 collections (ou
maps) comme il vient d'tre dcrit

page 151

R. Grin

Classe association pour une


association M:N

Association entre les employs et les projets


Cas d'un identificateur unique : la classe
association contient les attributs id (int),
employe
p y ((Employe),
p y ) projet
p j ((Projet)
j ) et
fonction (String)
L'attribut id est annot par @Id
Les attributs employe et projet sont
annots par @ManyToOne

L'association sera traduite par une classe


association
2 possibilits pour cette classe, suivant
qu'elle contient ou non un attribut
identificateur (@Id) unique

Le plus simple est de n'avoir qu'un seul


attribut identificateur

R. Grin

JPA

page 153

R. Grin

Exemple - 1 identificateur

@Entity
@Table(uniqueConstraints=@UniqueConstrain
t(columnNames={"EMPLOYE_ID","PROJET_ID"})
public class Participation {

JPA

JPA

page 154

Exemple - 2 identificateurs (1)

Si le schma relationnel est gnr daprs les


informations de mapping par les outils associs
au fournisseur de persistance, on peut ajouter
une contrainte d'unicit sur (EMPLOYE_ID,
PROJET ID) qui traduit le fait qu'un
PROJET_ID)
qu un employ
ne peut avoir 2 fonctions dans un mme projet :

R. Grin

page 152

Exemple - 1 identificateur

JPA

page 155

Si la base de donnes existe dj, il sera


frquent de devoir s'adapter une table
association qui contient les colonnes
suivantes (pas de colonne id):
n employe_id, cl

trangre
vers EMPLOYE
n projet_id, cl trangre vers PROJET
n fonction
et qui a (employe_id, projet_id) comme
cl primaire

R. Grin

JPA

page 156

26

Exemple - 2 identificateurs (2)

Exemple - 2 identificateurs

En ce cas, la solution est plus complexe, et


pas toujours portable dans l'tat actuel de la
spcification JPA
La solution donne dans les transparents
suivants convient pour TopLink Essentials et
Hibernate, les 2 fournisseurs de persistance
les plus utiliss ; elle na pas t teste sur
dautres fournisseurs

La difficult vient de l'criture de la classe


Participation

L'ide est de dissocier la fonction


d'identificateur des attributs employeId
p y
et
projetId de leur rle dans les associations
avec les classes Projet et Employe

R. Grin

R. Grin

JPA

page 157

JPA

page 158

Classes Employe et Projet

Exemple - 2 identificateurs

Pour viter les conflits au moment du flush,


les colonnes qui correspondent aux
identificateurs sont marqus non modifiables
ni insrables (pas de persistance dans la BD)
En effet, leur valeur sera mise par le mapping
des associations 1-N vers Employe et Projet
qui sera traduite par 2 cls trangres

R. Grin

JPA

page 159

On peut utiliser une classe Embeddable


ou une IdClass pour reprsenter la cl
composite de Participation
Le code suivant utilise une IdClass

JPA

R. Grin

JPA

page 160

Classe Participation (Id)

Classe Participation
(2 choix pour Id)

R. Grin

@Entity public class Employe {


@Id public int getId() { ... }
@OneToMany(mappedBy="employe")
public Collection<Participation>
getParticipations() { ... }
. . .
}
@Entity public class Projet {
@Id public int getId() { ... }
@OneToMany(mappedBy="projet")
public Collection<Participation>
getParticipations() { ... }
. . .
}

page 161

@Entity
@IdClass(ParticipationId.class)
public class Participation {
// Les identificateurs "read-only"
@Id
@Column(name="EMPLOYE_ID",
insertable="false", updatable="false")
public int getEmployeId() { }
@Id
@Column(name="PROJET_ID",
insertable="false", updatable="false")
public int getProjetId() { }
R. Grin

JPA

page 162

27

Classe Participation (champs)


private Employe employe;
private long employeId;
private Projet projet;
private long projetId;
private String fonction;
public Participation() { }

R. Grin

JPA

public Participation() { }
// Constructeur pour faciliter une
// bonne gestion des liens
public Participation(Employe e,
Projet
j
p) {
this.employe = e;
this.projet = p;
e.getParticipations().add(this);
p.getParticipations().add(this);
}
page 163

Il faut viter la possibilit quun bout


seulement de lassociation soit tablie et pour
cela, il faut quune seule classe sen charge
Pour cela, on peut faire grer lassociation
entire
par Projet, par Employe ou par
Participation

Le transparent suivant montre comment la


faire grer par le constructeur de
Participation

R. Grin

JPA

R. Grin

JPA

page 164

Participation (constructeurs)

tablir une association

Participation (constructeurs)

page 165

public Participation() { } // Pour JPA


public Participation(Employe employe,
Projet projet,
String fonction) {
this.employe
p y = employe;
p y
this.employeId = employe.getId();
this.projet = projet;
this.projetId = projet.getId();
employe.getParticipations.add(this);
projet.getParticipations.add(this);
this.fonction = fonction;
}
R. Grin

JPA

page 166

Classe ParticipationId

Participation (associations)

public class ParticipationId


implements Serializable {
private int employeId;
private int projetId;
public int g
p
getEmployeId()
p y
{ ... }
public void setEmployeId(int employeId)
{ ... }
public int getProjetId() { ... }
public void setProjetId(int projetId)
{ ... }
// Redfinir aussi equals et hasCode

// Les associations
@ManyToOne
public Employe getEmploye() {
return employe;
}
@ManyToOne
public Projet getProjet() {
return projet;
}
. . .
}
R. Grin

JPA

page 167

R. Grin

JPA

page 168

28

EAGER ou LAZY

Rcupration des entits associes


Lorsquune entit est rcupre depuis la
base de donnes par une requte (Query) ou
par un find, est-ce que les entits associes
doivent tre elles aussi rcupres ?
Si elles sont rcupres, est-ce que les entits
associes ces entits doivent elles aussi
tre rcupres ?
On voit que le risque est de rcuprer un trs
grand nombre dentits qui ne seront pas
utiles pour le traitement en cours

R. Grin

JPA

page 169

Rcupration retarde (LAZY)


Dans le cas o une entit associe nest pas
rcupre immdiatement, JPA remplace
lentit par un proxy , objet qui permettra
de rcuprer lentit plus tard si besoin est
Ce proxy contient la cl primaire qui
correspond lentit non immdiatement
rcupre
Il est possible de lancer une requte avec
une rcupration immdiate, mme si une
association est en mode LAZY (join fetch de
JPQL tudi plus loin)

R. Grin

JPA

page 171

Indiquer le type de rcupration


des entits associes
Lattribut fetch dune association permet
dindiquer une rcupration immdiate des
entits associes (FetchType.EAGER) ou une
rcupration
p
retarde ((FetchType.LAZY)
yp
) si le
comportement par dfaut ne convient pas
Exemple :

@OneToMany(mappedBy="departement",
fetch=FetchType.EAGER)
public Collection<Employe>
getEmployes()
R. Grin

JPA

page 173

JPA laisse le choix de rcuprer ou non


immdiatement les entits associes, suivant
les circonstances
Il suffit de choisir le mode de rcupration de
llassociation
association (LAZY ou EAGER)

Une requte sera la mme, quel que soit le


mode de rcupration
Dans le mode LAZY les donnes associes
ne sont rcupres que lorsque cest
vraiment ncessaire

R. Grin

JPA

page 170

Comportement par dfaut de JPA


Par dfaut, JPA ne rcupre immdiatement
que les entits associes par des
associations dont le but est One (une
seule entit lautre bout) : OneToOne et
M
ManyToOne
T O (mode
( d EAGER)
Pour les associations dont le but est
Many (une collection lautre bout),
OneToMany et ManyToMany, par dfaut, les
entits associes ne sont pas rcupres
immdiatement (mode LAZY)

R. Grin

JPA

page 172

Mode de rcupration
des attributs
Les attributs aussi peuvent tre rcuprs en
mode retard
Le mode de rcupration par dfaut est le
mode EAGER pour les attributs (ils sont
chargs en mme temps que lentit)
l entit)
Si un attribut est dun type de grande
dimension (LOB), il peut aussi tre marqu par
@Basic(fetch=FetchType.LAZY)
( utiliser avec parcimonie)
Cette annotation nest quune suggestion au
GE, quil peut ne pas suivre

R. Grin

JPA

page 174

29

Map pour association

Map pour association

A la place dune collection il est possible


dutiliser une map
En ce cas il faut annoter lassociation avec
@MapKey qui prcise la cl de la map qui doit
tre un des attributs de lentit contenue dans
la map
La classe de la cl doit avoir sa mthode
hashCode compatible avec sa mthode
equals et chaque cl doit tre unique parmi
toutes les autres cls de la map

R. Grin

R. Grin

JPA

page 175

Si lassociation est traduite par une map mais


na pas dannotation @KeyMap, la cl sera
considre tre lidentificateur de lentit

JPA

page 176

Exemple

Les employs dun dpartement peuvent tre


enregistrs dans une map dont les cls sont
les noms des employs (on suppose que 2
employs nont pas le mme nom)

Hritage

public class Departement {


...
@OneToMany(mappedBy="nom")
public Map<String,Employe> getEmployes(){
...
}
R. Grin

JPA

page 177

R. Grin

Stratgies

une table par classe ; les tables sont jointes


pour reconstituer les donnes (JOINED)

La stratgie une table distincte par classe


concrte est seulement optionnelle
(TABLE_PER_CLASS)

R. Grin

JPA

page 178

Une table par hirarchie

A ce jour, les implmentations de JPA doivent


obligatoirement offrir 2 stratgies pour la
traduction de lhritage :
n une seule table pour une hirarchie
dhritage
d
hritage (SINGLE
(SINGLE_TABLE)
TABLE)
n

JPA

page 179

Sans doute la stratgie la plus utilise


Valeur par dfaut de la stratgie de traduction
de lhritage
Elle est p
performante et p
permet le
polymorphisme
Mais elle induit beaucoup de valeurs NULL
dans les colonnes si la hirarchie est
complexe

R. Grin

JPA

page 180

30

Exemple

Nom de la table

A mettre dans la
@Entity
classe racine de
@Inheritance(strategy=
la hirarchie
InheritanceType.SINGLE_TABLE)
public abstract class Personne {...}

Si on choisit la stratgie une seule table


pour une arborescence dhritage la table a
le nom de la table associe la classe racine
de la hirarchie

@Entity
Employe par dfaut
@DiscriminatorValue("E")
public class Employe extends Personne {
...
}
R. Grin

JPA

page 181

R. Grin

Colonne discriminatrice (1)

Lannotation @DicriminatorColumn
permet de modifier les valeurs par dfaut
Ses attributs :
n name
n discriminatorType
n columnDefinition fragment SQL pour
crer la colonne
n length longueur dans le cas o le type
est STRING (31 par dfaut)

Une colonne de la table doit permettre de


diffrencier les lignes des diffrentes classes
de la hirarchie dhritage
Cette colonne est indispensable pour le bon
fonctionnement des requtes qui se limitent
une sous-classe
Par dfaut, cette colonne se nomme DTYPE
et elle est de type Discriminator.STRING
de longueur 31 (autres possibilits pour le
type : CHAR et INTEGER)

R. Grin

R. Grin

page 183

Exemple

JPA

JPA

page 184

Valeur discriminatrice

@Entity
@Inheritance
@DiscriminatorColumn(
name="TRUC",
discriminatorType="STRING",
yp
,
length=5)
public class Machin {

R. Grin

page 182

Colonne discriminatrice (2)

JPA

JPA

Chaque classe est diffrencie par une


valeur de la colonne discriminatrice
Cette valeur est passe en paramtre de
lannotation @DiscriminatorValue

page 185

Par dfaut cette valeur est le nom de la


classe

R. Grin

JPA

page 186

31

Une table par classe

Exemple

Toutes les classes, mme les classes


abstraites, sont reprsentes par une table
Ncessite des jointures pour retrouver les
proprits dune instance dune classe
Une colonne discriminatrice est ajoute
j
dans
la table qui correspond la classe racine de
la hirarchie dhritage
Cette colonne permet de simplifier certaines
requtes ; par exemple, pour retrouver les
noms de tous les employs (classe Personne
la racine de la hirarchie dhritage)

R. Grin

JPA

page 187

@Entity
@Inheritance(strategy=
InheritanceType.JOINED)
public abstract class Personne {...}
@Entity
@DiscriminatorValue("E")
public class Employe extends Personne {
...
}

R. Grin

Une table par classe concrte

R. Grin

R. Grin

JPA

page 189

@Entity
@Inheritance(strategy=
InheritanceType.TABLE_PER_CLASS)
public abstract class Personne {...}
@Entity
y
@Table(name=EMPLOYE)
public class Employe extends Personne {
...
}

Entit abstraite

page 190

Son tat sera persistant et sera utilis par les


sous-classes entits
Comme toute entit, elle pourra dsigner le
type retour dune requte (query) pour une
requte polymorphe

Lannotation @Entity ne shrite pas

Les sous-classes entits dune entit doivent


tre annote par @Entity

Une entit p
peut avoir une classe mre q
qui
nest pas une entit ; en ce cas, ltat de cette
classe mre ne sera pas persistant

JPA

JPA

Complments

Une classe abstraite peut tre une entit


(annote par @Entity)

R. Grin

page 188

Exemple

Stratgie seulement optionnelle


Pas recommand car le polymorphisme est
plus complexe obtenir (voir cours sur le
mapping objet-relationnel)
Chaque classe concrte correspond une
seule table totalement spare des autres
tables
Toutes les proprits de la classe, mme celles
qui sont hrites, se retrouvent dans la table

JPA

page 191

R. Grin

JPA

page 192

32

Classe mre persistante

Classe mre persistante

Une entit peut aussi avoir une classe mre


dont ltat est persistant, sans que cette
classe mre ne soit une entit
En ce cas, la classe mre doit tre annote
par @MappedSuperclass

Ltat de cette classe mre sera rendu


persistant avec ltat de la classe entit fille,
dans la mme table que cette classe entit

R. Grin

JPA

page 193

Cette classe mre nest pas une entit


Donc elle ne pourra pas tre renvoye par
une requte, ne pourra pas tre passe en
paramtre dune mthode dun
EntityManager ou dun
Query et ne pourra
tre le but dune association

R. Grin

Si toutes les entits ont des attributs pour


enregistrer la date de la dernire modification
et le nom de lutilisateur qui a effectu cette
modification, il peut tre intressant davoir
une classe abstraite Base,
B
mre de toutes les
entits qui contient ces attributs
Cette classe mre sera annote avec
@MappedSuperclass

JPA

page 194

Code de lexemple

Exemple

R. Grin

JPA

page 195

@MappedSuperclass
public abstract class Base {
@Id @GeneratedValue
private Long Id;
@Version
private
i t I
Integer
t g
version;
i
@ManyToOne
private User user;
@Temporal(value = TemporalType.TIMESTAMP)
private Date dateModif;
...
}
R. Grin

JPA

page 196

Classe mre non persistante


Une classe entit peut aussi hriter dune
classe mre dont ltat nest pas persistant
En ce cas, ltat hrit de la classe mre ne
sera pas persistant
La classe mre ne comportera aucune
annotation particulire lie la persistance

R. Grin

JPA

page 197

Requtes - JPQL

R. Grin

JPA

page 198

33

Rappel important
Toutes les entits retrouves par find,
getReference ou un query sont
automatiquement gres par le gestionnaire
dentits
Les modifications apportes ces entits sont
donc enregistres au prochain commit (mais
les nouveaux objets associs l'entit
retrouve ne sont pas automatiquement
persistants mme s'il y a une cascade sur
persist ; a ne marche que pour un appel
explicite de la mthode persist)

Cette section concerne les entits (et valeurs)


retrouves en interrogeant la base de donnes

R. Grin

JPA

page 199

R. Grin

find et getReference (de EntityManager)


permettent de retrouver une entit en donnant
son identificateur dans la BD
<T> T find(Class<T> classeEntit,
Obj t clPrimaire)
Object
lP i i )
<T> T get(Class<T> classeEntit,
Object clPrimaire)
Le rsultat sera null si aucune entit na cet
identificateur dans la base de donne

JPA

page 200

Exemple

Chercher par identit

R. Grin

JPA

page 201

Departement dept =
em.find(Departement.class, 10);

R. Grin

getReference

JPA

page 202

getReference

getReference renvoie une rfrence vers une


entit, sans que cette entit ne soit
ncessairement initialise
Le plus souvent il vaut mieux utiliser find

getReference peut tre (rarement) utilise


pour amliorer les performances quand une
entit non initialise peut tre suffisante, sans
que lentit entire soit retrouve dans la base
d d
de
donnes

Par exemple, pour indiquer une association dont


le but est unique (OneToOne ou ManyToOne) :

Departement dept =
em.getReference(Departement.class, 10);
Employe emp.setDepartement(dept);
R. Grin

JPA

page 203

R. Grin

JPA

page 204

34

tapes pour rcuprer des donnes

Il est possible de rechercher des donnes sur


des critres plus complexes que la simple
identit
Les tapes sont alors les suivantes :
1. Dcrire ce qui est recherch (langage
JPQL)
2. Crer une instance de type Query
3.

4.
R. Grin

Langage JPQL
Le langage JPQL (Java Persistence Query
Language) permet de dcrire ce que
lapplication recherche
Il ressemble beaucoup SQL

Initialiser la requte (paramtres,


pagination)
Lancer lexcution de la requte
JPA

page 205

R. Grin

Requtes sur les entits objet

R. Grin

R. Grin

JPA

page 207

Les entits sont dsignes par leur nom


Le nom dune entit est donn par lattribut
name de @Entity ; par dfaut cest le nom
terminal (sans le nom du paquetage) de la
classe

JPA

page 208

Exemples de requtes JPQL

Alias
Le texte des requtes utilise beaucoup les
alias de classe
Les attributs des classes doivent tre prfixs
par les alias
Une erreur frquente du dbutant est
doublier les alias en prfixe

R. Grin

R. Grin

JPA

page 206

Dsigner les entits

Les requtes JPQL travaillent avec le modle


objet et pas avec le modle relationnel
Les identificateurs dsignent les entits et
leurs proprits et pas les tables et leurs
colonnes
Les seules classes qui peuvent tre
explicitement dsignes dans une requte
(clause from) sont les entits

JPA

page 209

select e from Employe as e


select e.nom, e.salaire from Employe e
select e from Employe e
where e.departement.nom = 'Direction'
select d
d.nom,
nom avg(e
avg(e.salaire)
salaire)
from Departement d join d.employes e
group by d.nom
having count(d.nom) > 5

JPA

page 210

35

Type du rsultat (1)

Lexpression de la clause select peut tre


n une (ou plusieurs) expression entit ,
par exemple un employ (e par exemple)
n

Type du rsultat (2)

Lexpression ne peut tre une collection


(d.employes par exemple), bien que
TopLink le permette !

une (ou plusieurs) expression valeur ,


par exemple le nom et le salaire dun
employ (e.nom par exemple)

Si la requte renvoie des entits, elles sont


automatiquement gres par le GE (toute
modification sera rpercute dans la base)

R. Grin

JPA

page 211

Obtenir le rsultat de la requte

Pour le cas o une seule valeur ou entit est


renvoye, le plus simple est dutiliser la
mthode getSingleResult() ; elle renvoie
un Object

La mthode lance des exceptions ssilil ny


nya
pas exactement une entit qui correspond
la requte :
n EntityNotFoundException
n NonUniqueResultException

R. Grin

JPA

page 213

R. Grin

Pour le cas o une plusieurs valeurs ou


entits peuvent tre renvoyes, il faut utiliser
la mthode getResultList()

Elle renvoie une liste raw (pas gnrique)


des rsultats
rsultats, instance de java.util.List,
java util List
ventuellement vide si le rsultat est vide
Un message davertissement sera affich
durant la compilation si le rsultat est rang
dans une liste gnrique (List<Employe>
par exemple)

R. Grin

JPA

JPA

page 214

Exemple 1

Le type dun lment de la liste (ou de


lunique valeur ou entit renvoye) est
n Object
j
si la clause select ne comporte
p
quune seule expression
n Object[] si elle comporte plusieurs
expressions

R. Grin

page 212

Obtenir le rsultat de la requte

Type dun lment


du rsultat

JPA

page 215

String s = "select e from Employe as e";


Query query = em.createQuery(s);
List<Employe> listeEmployes =
(List<Employe>)query.getResultList();

R. Grin

JPA

page 216

36

Interface Query

Exemple 2
texte = "select e.nom, e.salaire "
+ " from Employe as e";
query = em.createQuery(texte);
List<Object[]> liste =
(List<Object[]>)query getResultList();
(List<Object[]>)query.getResultList();
for (Object[] info : liste) {
System.out.println(info[0] + " gagne "
+ info[1]);
}

R. Grin

JPA

page 217

Reprsente une requte


Une instance de Query (dune classe
implmentant Query) est obtenue par les
mthodes createQuery, createNativeQuery
ou createNamedQuery de linterface

f
EntityManager

R. Grin

Mthodes de Query (1)


List getResultList()
Object getSingleResult()
int executeUpdate()
Q
Query
y setMaxResults(int
(
nbResultats)
Query setFirstResult(int
positionDepart)
Query setFlushMode(FlushModeType
modeFlush)

R. Grin

R. Grin

page 219

Query setParameter(String nom,


Object valeur)
Query setParameter(String nom,
Date valeur, TemporalType
typeTemporel)
Query setParameter(String nom,
Calendar valeur, TemporalType
typeTemporel)

Types temporels
On a vu que les 2 types java temporels du
paquetage java.util (Date et Calendar)
ncessitent une annotation @Temporal

Ils ncessitent aussi un paramtre


supplmentaire pour la mthode
setParameter

JPA

JPA

page 220

Exemple

R. Grin

page 218

Mthodes de Query (2)

JPA

JPA

page 221

@Temporal(TemporalType.DATE)
private Calendar dateEmb;
em.createQuery("select e from employe e"
+ " where e.dateEmb between ?1 and ?2")
.setParameter(1, debut, TemporalType.DATE)
p
yp
.setParameter(2, fin, TemporalType.DATE)
.getResultList();

R. Grin

JPA

page 222

37

Types de requte

Paramtres des requtes

Requtes dynamiques dont le texte est


donne en paramtre de createQuery

Requtes natives particulires un SGBD


(pas portables) ; requte SQL (pas JPQL)
avec tables et colonnes (pas classes et
attributs)
Requtes nommes dont le texte est donne
dans une annotation de lentit concerne et
dont le nom est pass en paramtre de
createNamedQuery ; une requte nomme
peut tre dynamique ou native

R. Grin

JPA

page 223

Un paramtre peut tre dsign par son


numro (?n) ou par son nom (:nom)

Les valeurs des paramtres sont donnes


par les mthodes setParameter

Les paramtres sont numrots partir de 1


Un paramtre peut tre utilis plus dune fois
dans une requte
Lusage des paramtres nomms est
recommand (plus lisible)

R. Grin

Requte nomme (1)

page 224

Requte nomme (2)

Seules les entits peuvent contenir des


dfinitions de requtes nommes
Une requte nomme peut tre mise dans
nimporte quelle entit, mais on choisira le
plus souvent lentit qui correspond ce qui
est renvoy par la requte
Le nom de la requte nomme doit tre
unique parmi toutes les entits de lunit de
persistance ; on pourra, par exemple, prfixer
le nom par le nom de lentit : Employe.findAll

R. Grin

R. Grin

JPA

JPA

page 225

Les requtes nommes peuvent tre


analyse et prcompiles par le fournisseur
de persistance au dmarrage de lapplication,
ce qui peut amliorer les performances

Exemple de requte nomme


@Entity
@NamedQuery (
name = "findNomsEmployes",
query = "select e.nom from Employe as e
where upper(e.departement.nom) = :nomDept"
)
public class Employe extends Personne {
...

JPA

page 226

Exemples

Query query = em.createQuery(


"select e from Employe as e "
+ "where e.nom = ?1");
query.setParameter(1, "Dupond");
Query
y q
query
y = em.createQuery(
y
"select e from Employe as e "
+ "where e.nom = :nom");
query.setParameter("nom", "Dupond");

Query q =
em.createNamedQuery("findNomsEmployes");
R. Grin

JPA

page 227

R. Grin

JPA

page 228

38

Mode de flush

Plusieurs requtes nommes

Normalement (mode FlushMode.AUTO) un


flush des entits concernes par une requte
est effectu avant la requte pour que le
rsultat tienne compte des modifications
effectues en mmoire sur ces entits
Pour une requte il est possible d'viter ce
flush avec la mthode setFlushMode :
query.setFlushMode(FlushMode.COMMIT
);
Dans ce mode, seul un commit provoquera un
flush

Si une classe a plusieurs requtes nommes,


il faut les regrouper dans une annotation
@NamedQueries :
@NamedQueries({
@NamedQ er (
@NamedQuery(...),
)
@NamedQuery(...),
...
})

R. Grin

JPA

page 229

R. Grin

JPA

page 230

Clauses dun select

Les transparents suivants tudient en dtails


le langage JPQL

R. Grin

JPA

page 231

select : type des objets ou valeurs


renvoyes
from : o les donnes sont rcupres
where : slectionne les donnes
group by : regroupe des donnes
having : slectionne les groupes (ne peut
exister sans clause group by)
order by : ordonne les donnes

R. Grin

JPA

page 232

Polymorphisme dans les requtes

Les mots-cls select, from, distinct,


join, sont insensibles la casse

R. Grin

JPA

page 233

Toutes les requtes sont polymorphes : un


nom de classe dans la clause from dsigne
cette classe et toutes les sous-classes
Exemple :
select count(a) from Article as a
compte le nombre dinstances de la classe
Article et de tous les sous-classes de
Article

R. Grin

JPA

page 234

39

Rgle pour les expressions


de chemin

Expression de chemin

Les requtes peuvent contenir des


expressions de chemin pour naviguer entre
les entits en suivant les associations
dclares dans le modle objet (les
annotations @OneToOne,
@O T O
@O T M
@OneToMany,
))
La notation pointe est utilise

R. Grin

JPA

page 235

Une navigation peut tre chane une


navigation prcdente la condition que la
navigation prcdente ne donne quune
qu une seule
entit (OneToOne ou ManyToOne)

Dans le cas o une navigation aboutit


plusieurs entits, il est possible dutiliser la
clause join tudie plus loin pour obtenir
ces entits

R. Grin

Exemples

select e.nom
from Employe as e
where e.departement.nom = 'Qualit'

e.projets.nom nest pas autoris car


e.projets est une collection (voir clause
join)
JPA

page 237

Dans une clause select, indique que les


valeurs dupliques sont limines (la requte
ne garde quune seule des valeurs gales)
Exemple :
select distinct e.departement
from Employe e

R. Grin

Il est possible de renvoyer des instances dune


classe dont le constructeur prend en paramtre
des informations rcupres dans la base de
donnes
La classe doit tre dsigne par son nom
complet (avec le nom du paquetage)
Exemple :

select new p1.p2.Classe(e.nom, e.salaire)


from Employe e

JPA

JPA

page 238

Clauses where et having

new

R. Grin

page 236

distinct

Si e est un alias pour Employe,


n e.departement dsigne le
dpartement dun employ
n e.projets dsigne la collection de
projets
p
j
auxquels
q
p
participe
p un employ
p y

R. Grin

JPA

page 239

Ces clauses peuvent comporter les mots-cls


suivants :
n [NOT] LIKE, [NOT] BETWEEN, [NOT] IN
n AND, OR, NOT
n [NOT] EXISTS
n ALL, SOME/ANY
n IS [NOT] EMPTY, [NOT] MEMBER OF

R. Grin

JPA

page 240

40

Exemple

having

select d.nom, avg(e.salaire)


from Departement d join d.employes e
group by d.nom
having count(d.nom) > 3

Restriction : la condition doit porter sur


lexpression de regroupement ou sur une
fonction de regroupement portant sur
lexpression de regroupement
Par exemple, la requte suivante provoque
une exception :

select d.nom, avg(e.salaire)


from Departement d join d.employes e
group by d.nom
having avg(e.salaire) > 1000
R. Grin

JPA

page 241

R. Grin

Sous-requte (1)
Les clauses where et having peuvent
contenir des sous-requtes
Exemple :

{ALL | ANY | SOME} (sous-requte)


fonctionne comme dans SQL
Exemple :

select e from Employe e


where
h
e.salaire
l i
>
>= (
select e2.salaire from Employe e2
where e2.departement = 10)

JPA

select e from Employe e


where
h
e.salaire
l i
>
>= ALL (
select e2.salaire from Employe e2
where e2.departement =
e.departement)

page 243

R. Grin

Une sous-requte peut tre synchronise


avec une requte englobante
Exemple :

page 244

[not]exists fonctionne comme avec SQL

Exemple :
select emp from Employe e
where exists (
select ee from Employe ee
where ee = e.epouse)

select e from Employe e


where
h
e.salaire
l i
>
>= ALL (
select e2.salaire from Employe e2
where e2.departement =
e.departement)

JPA

JPA

Sous-requte - exists

Sous-requte synchronise

R. Grin

page 242

Sous-requte (2)

R. Grin

JPA

page 245

R. Grin

JPA

page 246

41

Exemple

Contre-exemple

select e.nom,
e.departement.nom,
e.superieur.departement.nom
from Employe e

R. Grin

JPA

page 247

d.employes.nom est interdit car


d.employes est une collection

Pour avoir les noms des employs dun


dpartement, il faut utiliser une jointure

R. Grin

Jointure

page 248

Types de jointures

Une jointure permet de combiner plusieurs


entits dans un select
Rappel : il est possible dutiliser plusieurs
entits dans une requte grce la
navigation
i ti
Une jointure est le plus souvent utilise pour
rsoudre les cas (interdit par JPA) o
n lexpression du select serait une collection
n la navigation partirait dune collection

R. Grin

R. Grin

JPA

JPA

page 249

Il existe plusieurs types de jointures :


n jointure interne (jointure standard join)
n jointure externe (outer join)
n

j
jointure
avec rcupration
p
de donnes en
mmoire (join fetch)

jointure la SQL dans un where pour


joindre suivant des champs qui ne
correspondent pas une association
(where e1.f1 = e2.f2)
JPA

page 250

Autres exemples

Exemple

Si on veut tous les employs dun


dpartement, la requte suivante nest pas
permise par la spcification JPA (bien que
TopLink lautorise) :
select d
d.employes
employes
from Departement d
where d.nom = 'Direction'

Une jointure est ncessaire :


select e
from Departement d join d.employes e
where d.nom = 'Direction'

R. Grin

JPA

page 251

select e.nom
from Departement d
join d.employes e
where d.nom = 'Direction'
select e.nom, parts.projet.nom
from Employe e
join e
e.participations
participations parts
select e.nom, d.nom
from Employe e, Departement d
where d = e.departement
select e, p
from Employe e
join e.participations parts
join parts.projet p
R. Grin

JPA

page 252

42

Jointure externe

join fetch

select e, d
from Employe e left join e.departement d

ramnera aussi les employs qui ne sont pas


associs un dpartement

R. Grin

JPA

page 253

Permet dviter le problme des N + 1


selects
Lentit plac droite de join fetch sera
cre en mmoire en mme temps que
lentit de la clause select
Le select SQL gnr sera une jointure
externe qui rcuprera les donnes de toutes
les entits associes en mme temps que les
donnes des entits principales de la requte

R. Grin

Exemple

Cette requte rcuprera tous les employs


mais, en plus, lappel de la mthode
getDepartement() ne provoquera aucune
interrogation de la base de donnes puisque
le join fetch aura dj charg tous les
dpartements des employs
Lexemple suivant prcharge les collections
de participations aux projets

JPA

page 254

Exemple

select e
from Employe e join fetch e.departement

R. Grin

JPA

page 255

String texteQuery =
"select e "
+ " from Employe as e "
+ "
join fetch e.participations";
Q
Query
query = em.createQuery(texteQuery);
t Q
(t t Q
)
listeEmployes =
(List<Employe>)query.getResultList();

R. Grin

JPA

page 256

Doublons possibles avec join fetch


La requte SQL lance par un join fetch fait une
jointure pour rcuprer les entits prcharges
Ensuite, les entits prcharges sont enleves
des lignes du rsultat pour quelles
napparaissent
pp
p
pas dans le rsultat du q
query
y
Ce traitement, impos par la spcification de
JPA, peut occasionner des doublons dans le
rsultat si le select renvoie des valeurs
Pour les viter, il faut ajouter loprateur
DISTINCT dans le texte de la requte ou placer
le rsultat dans une collection de type Set

R. Grin

JPA

page 257

Il existe aussi des variantes outer join


de join fetch pour rcuprer dans le
select des entits non jointes une autre
entit

R. Grin

JPA

page 258

43

Produit cartsien (1)

Produit cartsien (2)

Le prchargement par join fetch de plusieurs


collections dune mme entit peut occasionner
un phnomne nuisible aux performances
En effet, le select SQL gnr par le
fournisseur de persistance peut rcuprer un
produit cartsien des lments des collections
Le fournisseur sarrange pour ne garder que les
informations ncessaires mais le select peut
renvoyer un trs grand nombre de lignes qui
vont transiter par le rseau

R. Grin

JPA

page 259

Dans le cas o les collections contiennent de


nombreux lments il faut donc vrifier avec les
logs du fournisseur si le select gnr renvoie
effectivement un trop grand nombre de lignes
et changer de stratgie de rcupration si cest
le cas (rcuprer sparment les informations
sur les collections)
En effet, si 2 collections contiennent 20
lments, et si 1000 entits principales sont
renvoyes le select renverra 400.000 lignes !
(au lieu de 40.000 si on ramne les
informations avec 2 join fetch spars)

R. Grin

Une entit principale ep avec 2 associations de


lentit principale avec dautres entits e2 et e3
Pour rcuprer en mmoire les entits
principales et associes, le select gnr
risque
q dtre du type
yp suivant ((consulter les logs
g
du fournisseur de persistance) :

select ep.*, e2.*, e3.*


from EP ep
left outer join E2 e2 on ep.id_e2 =
e2.id
left outer join E3 e3 on ep.id_e3 =
e3.id
JPA

page 261

Fonctions de chanes de caractres : concat,


substring, trim, lower, upper, length,
locate (localiser une sous-chane dans une
autre)
Fonctions arithmtiques : abs, sqrt, mod,
size
i (dune
(d
collection)
ll ti )
Fonctions de date : current_date,
current_time, current_timestamp
Fonctions de regroupement : count, max, min,
avg

Spcification JPA pour plus dinformations,

R. Grin

Travail avec les collections


Une expression chemin dun select peut
dsigner une collection
Exemples :
departement.employes
facture.lignes
La fonction size donne la taille de la collection
La condition is [not] empty est vraie si
la collection est [nest pas] vide
La condition [not] member of indique si
une entit appartient une collection
JPA

JPA

page 262

Exemples

R. Grin

page 260

Fonctions

Exemple

R. Grin

JPA

page 263

select d
from Departement
where e.employes is empty
select e
from Employe
p y e
where :projet member of
e.participations.projet

R. Grin

JPA

page 264

44

Parcours dune collection

Parcours dune collection

La requte suivante ne donnera pas tous les


produits lis une facture ; elle provoquera
une exception lexcution

select distinct f.lignes.produit


from Facture as f

select distinct l
l.produit
produit
from Facture as f join f.lignes as l

En effet, il est interdit de composer une


expression de chemin en partant dune
expression qui dsigne une collection
(f.lignes)

R. Grin

JPA

Le plus simple est dutiliser un join dans le


from avec un alias ( l dans lexemple cidessous) pour dsigner un lment qui
parcourt la collection :

page 265

Lautre solution, in , une ancienne syntaxe


hrite dEJB 2, nest pas recommande

R. Grin

Pagination du rsultat

JPA

page 266

Enchanement des mthodes

Query setMaxResults(int n) : indique


le nombre maximum de rsultats retrouver
Query setFirstResult(int n) : indique
la position du 1er rsultat retrouver
(numrot partir de 0)

Les mthodes setParameter,


setMaxResults renvoient le Query modifi

On peut donc les enchaner


Exemple
p :

R. Grin

R. Grin

JPA

page 267

em.createQuery(texteQuery)
.setParameter(nomParam, valeurParam)
.setMaxResults(30)
.getResultList();

JPA

page 268

Utilit
Pour les performances il est parfois mauvais
de charger toutes les donnes modifier
dans des instances dentits
En ce cas, EJBQL permet de modifier les
donnes de la base directement, sans crer
les entits correspondantes

Oprations de modification
en volume

R. Grin

JPA

page 269

R. Grin

JPA

page 270

45

Cas dutilisation

Exemple

Si on veut augmenter de 5% les 1000


employs de lentreprise il serait mauvais de
rcuprer dans 1000 instances les donnes
de chaque employs, de modifier le salaire
d chacun,
de
h
puis
i d
de sauvegarder
d lles d
donnes

Un simple ordre SQL

em.getTransaction().begin();
String ordre =
"update Employe e " +
" set e.salaire = e.salaire * 1.05";
Query q = em.createQuery(ordre);
int nbEntitesModif = q.executeUpdate();
em.getTransaction().commit();

update employe
set salaire = salaire * 1.05

sera normment plus performant

R. Grin

JPA

page 271

R. Grin

Les ordres de modification en volume


rfrencent les classes et les proprits des
classes mais ils ne crent aucune entit en
mmoire et ils ne mettent pas jour les entits
dj
j p
prsentes en mmoire
update Entite as alias
set alias.prop1 = val1, alias.prop2 = val2,
where condition
La condition peut tre aussi complexe que la
condition dun select

JPA

page 272

Remarques

Syntaxe

R. Grin

JPA

page 273

Les modifications doivent tre faites dans une


transaction
Le plus souvent il faut isoler le lancement de
ces oprations dans une transaction part, ou
au moins excuter ces oprations au dbut
dune transaction avant la rcupration dans la
base dentits touches par lopration
En effet, les entits en mmoire ne sont pas
modifies par lopration et elles ne
correspondront alors donc plus aux nouvelles
valeurs modifies dans la base de donnes

R. Grin

JPA

page 274

Exceptions non contrles

Exceptions

R. Grin

JPA

page 275

JPA nutilise que des exceptions non contrles


(descendantes de RuntimeException)

JPA utilise les 2 exceptions


IllegalArgumentException et
IllegalStateException du paquetage
java.lang

Sinon, toutes les autres exceptions sont dans le


paquetage javax.persistence et hritent de
PersistenceException

R. Grin

JPA

page 276

46

Types dexception

Exception et rollback

NonUniqueResultException
NoResultException
EntityNotFoundException
EntityExistsException
y
p
TransactionRequiredException
RollbackException
OptimisticLockException

Toute les exceptions de type


PersistenceException provoquent un
rollback, sauf
NonUniqueResultException et
NoRes ltE ception
NoResultException

Rappel : si laccs se fait par proprits, une


RuntimeException leve par une mthode
daccs une proprit provoque un rollback
de la transaction en cours

R. Grin

JPA

page 277

R. Grin

JPA

page 278

2 types de transactions
Les transactions locales une ressource,
fournies par JDBC sont attaches une
seule base de donnes
Les transactions JTA, ont plus de
fonctionnalits que les transactions JDBC ;
en particulier elles peuvent travailler avec
plusieurs bases de donnes

Transaction

R. Grin

JPA

page 279

R. Grin

Elles sont tudies dans la dernire section


de ce support de cours

R. Grin

JPA

page 280

Transactions dans Java SE


(sans serveur dapplications)

Transactions dans Java EE

JPA

page 281

Daprs la spcification JPA, dans Java SE,


les fournisseurs de persistance doivent
supporter les transactions locales une
ressource mais ne sont pas obligs de
ressource,
supporter les transactions JTA
La dmarcation des transactions est choisie
par le dveloppeur
Les contextes de persistance peuvent couvrir
plusieurs transactions

R. Grin

JPA

page 282

47

EntityTransaction

EntityTransaction

En dehors dun serveur dapplications, une


application doit utiliser linterface
javax.persitence.EntityTransaction
pour travailler avec des transactions locales
une ressource
Une instance de EntityTransaction peut
sobtenir par la mthode getTransaction()
de EntityManager

public interface EntityTransaction {


public void begin();
public void commit();
public void rollback();
public
bli void
id setRollbackOnly();
tR llb kO l ()
public boolean getRollbackOnly();
public void isActive();
}

R. Grin

R. Grin

JPA

page 283

EntityManager em;
...
try {
em.getTransaction().begin()
...
em.getTransaction().commit();
}
finally {
em.close();
}
JPA

page 284

Rollback (1)

Exemple

R. Grin

JPA

page 285

En cas de rollback,
n rollback dans la base de donnes
n le contexte de persistance est vid ; toutes
les entits deviennent dtaches

R. Grin

JPA

page 286

Transaction et contexte
de persistance

Rollback (2)
Les instances dentits Java gardent les
valeurs quelles avaient au moment du rollback
Mais ces valeurs sont le plus souvent fausses
Il est donc rare dutiliser ces entits en les
rattachant par un merge un GE

Le plus souvent il faut relancer des requtes


pour rcuprer des entits avec des valeurs
correctes

R. Grin

JPA

page 287

Quand un GE nest pas gr par un container


le contexte de persistance nest pas ferm
la fin dune transaction
Quand
Q
d un GE estt gr
par un container
t i
ett
que le contexte de persistance nest pas de
type tendu , le contexte est ferm la fin
dune transaction

R. Grin

JPA

page 288

48

Synchronisation dun GE
avec une transaction

Modifications et commit

Synchronisation dun GE avec une transaction :


le GE est enregistr auprs de la transaction ;
un commit de la transaction provoquera alors
automatiquement un flush du GE (le GE est
averti lors du commit)
En dehors dun serveur dapplications (avec
Java SE), un GE est obligatoirement
synchronis avec les transactions (quil a
lances par la mthode begin() de
EntityTransaction)

R. Grin

JPA

page 289

Les modifications effectues sur les entits


gres sont enregistres dans la base de
donnes au moment dun flush du contexte de
persistance
Si le GE est synchronis la transaction en
cours, le commit de la transaction enregistre
donc les modifications dans la base
Les modifications sont enregistres dans la
base, mme si elles ont t effectues avant le
dbut de la transaction (avant tx.begin()
dans Java SE)

R. Grin

JPA

page 290

GE et threads
Une fabrique de GE peut tre utilise sans
problme par plusieurs threads
Mais un GE ne doit tre utilis
concurremment que par un seul thread

Concurrence

R. Grin

JPA

page 291

R. Grin

Entits et threads
Les entits ne sont pas prvues pour tre
utilises par plusieurs threads en mme temps
Si a doit tre le cas, lapplication doit prendre
toutes ses prcautions pour viter les
problmes
Cest aussi le rle de lapplication dempcher
quune entit ne soit gre par plusieurs GE
en mme temps
Le rle du fournisseur de persistance
nintervient pas pour ces cas
JPA

page 292

Concurrence BD

R. Grin

JPA

page 293

Le fournisseur de persistance peut apporter


automatiquement une aide pour viter les
problmes daccs concurrents aux donnes
de la BD, pour les entits gres par un GE

R. Grin

JPA

page 294

49

Exemple de problme de
concurrence BD

Gestion de la concurrence

Une entit est rcupre depuis la BD (par


un find par exemple)

Par dfaut, le fournisseur de persistance gre


les problmes daccs concurrents aux entits
gres par un GE avec une stratgie optimiste

Lentit est ensuite modifie par lapplication


puis la transaction est valide
Si une autre transaction a modifi entretemps les donnes de la BD correspondant
lentit, la transaction doit tre invalide

R. Grin

JPA

page 295

R. Grin

JPA

page 296

Exemple

@version
Annote un attribut dont la valeur reprsentera
un numro de version (incrment chaque
modification) pour lentit et sera utilise pour
savoir si ltat dune entit a t modifie entre
2 moments diffrents (stratgie optimiste)
Lattribut doit tre de type int, Integer,
short, Short, long, Long ou
java.sql.TimeStamp (si possible, viter ce
dernier type)
Lapplication ne doit jamais modifier un tel
attribut (modifi par JPA)

R. Grin

JPA

page 297

@Version
private int version;

R. Grin

Entit versionne

JPA

page 298

lock(entite, mode)

Cest une entit qui possde un attribut qui


possde lannotation @version (ou le tag
correspondant dans les fichiers XML)

R. Grin

JPA

page 299

Sert protger une entit contre les accs


concurrents pour les cas o la protection
offerte par dfaut par le fournisseur ne suffit
pas
Cette entit doit tre versionne (sinon, le
traitement nest pas portable) et dj gre

R. Grin

JPA

page 300

50

Modes de blocage

READ

Lnumration LockModeType (paquetage


javax.persistence) dfinit 2 modes
READ : les autres transactions peuvent lire
lentit mais ne peuvent pas la modifier
WRITE : comme READ, mais en plus lattribut
de version est incrment, mme si lentit
na pas t modifie (utilit explique dans
les transparents suivants)

R. Grin

R. Grin

JPA

page 301

Empche les lectures non rptables sur les


donnes de la BD associes lentit
Sans ce blocage, on na pas lassurance
davoir une lecture rptable avec des query
qui renvoient des dattributs dentit (par
exemple employe.nom)
Le fournisseur de persistance peut choisir
une stratgie pessimiste (du type select for
update ) ou optimiste

Le blocage rel peut ntre effectu quau


moment du flush ou du commit, quelle que soit
lemplacement du read dans le code Java

Sil y a un problme, une exception


OptimisticLockException peut tre

lance

JPA

page 303

Un bilan qui calcule le total des salaires des


employs pour chaque dpartement doit
interdire quun employ ne change de
dpartement pendant le traitement, en passant
du dpartement
p
10 au dpartement
p
20
Sinon, cet employ sera compt 2 fois : aprs
avoir fait le calcul du total du dpartement 10,
on va faire une requte pour rcuprer les
employs du dpartement 20 et retrouver
lemploy dj dcompt dans le dpartement
10

R. Grin

Utilit des blocages READ

JPA

page 304

WRITE

Pour viter ce problme, les employs


peuvent tre bloqus en mode READ, au fur
et mesure de leur prise en compte pour le
calcul du total des salaires de leur
d t
dpartement
t
Le blocage peut tre pessimiste (select for
update sur les lignes bloques) ou optimiste ;
dans ce dernier cas le traitement recevra une
exception si loptimisme tait injustifi

R. Grin

R. Grin

JPA

page 302

Une situation viter

READ

R. Grin

JPA

page 305

Force une incrmentation de la version


Pour certains traitements il est intressant de
faire considrer que lentit a t modifie
mme si aucun de ses attributs na t
modifi
Dans lexemple qui suit le blocage WRITE
vite en quelque sorte les problmes de
lignes fantmes avec les associations qui
concernent une entit

JPA

page 306

51

Utilit des blocages WRITE (1)

WRITE

En effet, sans le blocage WRITE , le


fournisseur de persistance incrmente
automatiquement le numro de version si une
entit est modifie mais pas si les liens des
associations
i ti
quii partent
t td
de llentit
tit sontt
modifies (voir cependant la remarque qui
suit lexemple donn dans les transparents
suivants)

R. Grin

JPA

page 307

Une entte de facture contient un champ dans


lequel est stock le total de la facture
Supposons que le calcul de ce total est
effectu par un processus part du processus
de lajout
l ajout des lignes de la facture
Lorsquune ligne de facture est ajoute une
facture, len-tte de la facture nest pas
modifie donc le fournisseur de persistance
nincrmente pas le numro de version de
len-tte

R. Grin

Utilit des blocages WRITE (2)


Une ligne peut tre ajoute une facture sans
que le traitement qui calcule le total ne sen
rende compte ; il y aura inconsistance entre ce
total et les lignes de la facture
Si len
l en-tte
tte est bloque en criture pendant
lajout dune ligne de facture, le traitement qui
effectue le calcul du total sapercevra que la
facture a chang pendant le calcul puisque le
numro de version aura t incrment et il
ny aura pas inconsistance

R. Grin

JPA

page 309

JPA

page 308

Remarque
La spcification JPA ne dit pas avec prcision
quand le numro de version est incrment
Certains certains fournisseurs de persistance
comme Hibernate incrmentent le numro de
version quand les collections dune entit
sont modifies
Dans ce cas le blocage Write sera tout de
mme utile si, par exemple, un des lments
de la collection est modifi, par exemple le
prix dun produit compris dans la facture

R. Grin

JPA

page 310

Niveau disolation

Le fournisseur suppose que le SGBD gre la


base de donnes avec un niveau disolation
READ COMMITED (voir cours sur les BD)

R. Grin

JPA

page 311

Entit dtache

R. Grin

JPA

page 312

52

Cas dutilisation
Les entits dtaches sont surtout utiles dans
les applications multi-tiers (avec Java EE et
un serveur dapplications)
Cette section survole les possibilits offertes
par les entits dtaches
Les subtilits des entits dtaches sont
exposes dans le support complmentaire
JPA et serveurs dapplications

R. Grin

R. Grin

JPA

page 313

Une application multi-tiers


Le serveur dapplication rcupre des
donnes dans la BD
Ces donnes sont p
passes la couche client,
montres lutilisateur qui peut les modifier
Les modifications sont repasses au serveur
et enregistres dans la BD
Les entits dtaches facilitent
limplmentation dun tel cas dutilisation

Utilisation des entits dtaches

La mthode merge de EntityManager


permet dobtenir une entit gre partir
dune entit dtache
Sa signature :
<T> T merge(T entit)

R. Grin

R. Grin

JPA

page 315

page 314

Rattachement

Une fois dtaches les entits peuvent tre


passes la couche cliente
La couche cliente peut modifier les entits
dtaches
Ces entits peuvent ensuite tre rattaches
un GE et les modifications effectues dans la
couche cliente peuvent tre alors
enregistres dans la base de donnes lors
d'un flush

JPA

Attention, lentit passe en paramtre nest


pas rattache ; cest lentit renvoye par la
mthode merge qui est rattache ; cette
entit a le mme tat et la mme cl primaire
que lentit passe en paramtre
JPA

page 316

tat dune entit dtache

Si lentit passe en paramtre de merge est


dj gre par le GE, elle est renvoye par la
mthode merge

R. Grin

JPA

page 317

Ltat dune entit dtache peut ne pas tre


entirement disponible

R. Grin

JPA

page 318

53

tat dune entit

Attribut disponible

Pour des raisons de performances, l'tat dune


entit gre par un GE peut ne avoir t
compltement rcupr dans la BD
(rcupration retard ; lazy)
Le reste de ltat
l tat ne sera rcupr,
rcupr avec laide
l aide
du GE, que lorsque lentit en aura vraiment
besoin
Si lentit est dtache alors quune partie de
son tat na pas encore t rcupre, la
partie manquante de lentit dtache ne sera
pas disponible

R. Grin

R. Grin

JPA

page 319

Association dune entit dtache

Si une association dun objet dtach a le


mode de rcupration LAZY, il est possible
que lassociation ne puisse tre rcupre
(dpend des circonstances et des fournisseurs
d JPA)
de

R. Grin

JPA

page 321

Rendre accessible ltat


dune entit dtache

Un attribut persistant dune entit est


immdiatement disponible dans les 2 cas
suivants :
n lattribut a dj t utilis
n lattribut na pas t marqu par
fetch=LAZY
(par dfaut, les valeurs des attributs sont
charges en mmoire)

page 320

Association lazy disponible

Si une association dun objet dtach a le


mode de rcupration LAZY, il est possible
de naviguer travers cette association si
n lapplication a dj effectu cette
navigation
n ou si lassociation a t charge par un
join fetch lors dune requte

R. Grin

JPA

page 322

Rcuprer une association avant


le dtachement

2 solutions pour accder tout ltat dune


entit dtache
Lapplication rcupre tout ltat de lentit
gre avant le dtachement
Lapplication rattache lentit par la mthode
merge pour rcuprer ltat manquant

R. Grin

R. Grin

JPA

JPA

page 323

Si le but est une entit (OneToOne ou


ManyToOne), il suffit de lire une des
proprits de lentit
Si le but est une collection (OneToMany ou
ManyToMany), lappel de la mthode size()
de la collection suffit le plus souvent

JPA

page 324

54

Conflit de concurrence

Entit dtache et concurrence

Si les donnes de la BD associe un objet


dtach ont t modifies depuis le
dtachement de lobjet, merge lance une
exception, ou le commit chouera
Tout se passe donc comme si un conflit de
concurrence avait t dtect (avec une
stratgie optimiste)

Avant que les modifications sur lentit


dtache ne soient enregistres dans la BD,
lentit doit tre rattache un contexte de
persistance (celui dorigine ou un autre)
A ce moment, ou au moment du commit qui
enregistre vraiment les modifications, le
contexte de persistance vrifie quil ny a pas
de conflit de concurrence

R. Grin

R. Grin

JPA

page 325

JPA

page 326

Dtachement automatique

Dans Java SE, quelques situations provoquent


un dtachement automatique des entits
gres :
n Aprs un rollback
n Aprs un clear du GE
n Aprs la fermeture du GE

R. Grin

JPA

page 327

Configuration dune unit de


persistance

R. Grin

page 328

Configuration dune unit de


persistance

Fichier persistence.xml
Les informations doivent tre donnes dans un
fichier persistence.xml
Dans un environnement non gr, ce fichier doit
se situer dans le rpertoire META-INF dun des
rpertoires
t i
d
du classpath
l
th
Dans un serveur dapplications, le rpertoire
META-INF peut se trouver divers endroits :
dans WEB-INF/classes, un fichier jar de WEBINF/lib, un fichier jar de la racine dun fichier
EAR, (voir spcification pour la liste
complte)

R. Grin

R. Grin

JPA

JPA

page 329

Dans un environnent non gr par un serveur


dapplications, il est ncessaire de donner les
informations pour la connexion la base de
donnes

JPA

page 330

55

Configuration dune unit de


persistance

Le fichier persistence.xml donne dautres


informations, comme les noms des classes
entits, la configuration de lenvironnement de
mis
i au point
i t (l
(logging,
i
affichage
ffi h
des
d ordres
d
SQL
lancs dans le SGBD,) ou des proprits
particulires au driver du fournisseur de
persistance

R. Grin

JPA

page 331

Section properties

persistence.xml
<persistence
xmlns="http://java.sun.com/xml/ns/persistence"
version= "1.0" >
<persistence-unit name="Employes"
transaction-type="RESOURCE_LOCAL">
<class>p1.Employe</class>
p
p y /
<class>p1.Dept</class>
<properties>
. . . <! Voir transparent suivant-->
</properties>
</persistence-unit>
</persistence>
R. Grin

JPA

page 332

Exemple de section properties

La section properties dpend du


fournisseur des fonctionnalits dcrites dans
la spcification JPA
Elle contient les informations pour la
connexion mais aussi dautres informations
pour le logging ou la cration automatique
des tables si elle nexistent pas dj ; il faut
consulter la documentation du fournisseur

<properties>
<property
name="toplink.jdbc.driver"
value="oracle.jdbc.OracleDriver"/>
<property
name="toplink.jdbc.url"
li k jdb
l
value="jdbc:oracle:thin:@...:INFO "/>
<property name="toplink.jdbc.user"
value="toto"/>
<property name="toplink.jdbc.password"
value="mdp"/>
</properties>

R. Grin

R. Grin

JPA

page 333

Source de donnes
Lorsque JPA est utilis avec un serveur
dapplications, une source de donnes fournie
par le serveur dapplications est le plus
souvent utilise pour obtenir les connexions
(voir DataSource
D t S
dans le cours sur JDBC)

On pourra alors trouver :


<persistence-unit name="Employe">
<jta-data-source>jdbc/EmployeDS</jtadata-source>
</persistence-unit name=Employe>
JPA

page 334

Configuration dynamique

R. Grin

JPA

page 335

Les informations pour la connexion la base


peuvent ntre connues qu lexcution et
pas au moment de lcriture du code
En ce cas, il est possible de ne donner les
informations que lors de la cration de la
fabrique par la classe Persistence

Il suffit de passer la mthode


createEntityManagerFactory une map
qui contient les proprits qui crasent les
valeurs contenues dans persistence.xml

R. Grin

JPA

page 336

56

Exemple

Les ajouts de TopLink

// Saisie du nom et du mot de passe


. . .
// Configuration de la connexion
Map props = new HashMap();
props.put("toplink.jdbc.user",
t("t li k jdb
" nom);
)
props.put("toplink.jdbc.password", mdp);
EntityManagerFactory emf =
Persistence
.createEntityManagerFactory(
"employes", props);

R. Grin

R. Grin

JPA

page 337

TopLink a des extensions par rapport la


norme JPA
Par exemple,
n logging
gg g
n gnration automatique de tables
n

Gnration automatique des tables


La proprit toplink.ddl-generation
permet de crer automatiquement les tables
au moment de la cration de la fabrique de
gestionnaires dentits
Cette proprit peut avoir 3 valeurs :
n none : aucune cration automatique
n create-tables : les tables sont cres
si elles nexistent pas dj
n drop-and-create-tables : si une table
existe dj, elle est dabord supprime
avant dtre recre (utile pour les tests)

JPA

page 338

Exemple

R. Grin

JPA

page 339

<properties>
. . .
<property name="toplink.ddl-generation"
value="drop-and-create-tables"/>
</
</properties>
ti >

R. Grin

R. Grin

R. Grin

page 341

page 340

Proprit toplink.applicationlocation indique le nom du rpertoire qui


contiendra les fichiers contenant les ordres
DDL de cration et de suppression des tables
(l rpertoire
(le
t i courantt par df
dfaut)
t)

toplink.ddl-generation.output-mode
indique ce qui sera fait avec les fichiers DDL
Valeurs possibles :
n sql-script gnre les fichiers mais ne
les excute pas
n database excute les ordres DDL mais
ne gnre pas les fichiers
n both gnre les fichiers et les excute
(valeur par dfaut)
JPA

JPA

JPA

page 342

57

logging (1)

toplink.create-ddl-jdbc-file-name
indique le nom du fichier qui contiendra les
ordres de cration des tables ; par dfaut,
createDDL.jdbc
toplink.drop-ddl-jdbc-file-name
idem pour la suppression des tables ; par
dfaut, dropDDL.jdbc

La proprit toplink.logging.level
peut avoir les valeurs
n OFF : aucune information
n SEVERE : uniquement les erreurs
n WARNING : les avertissements (et les erreurs)
n INFO (valeur par dfaut) : assez peu
dinformation en plus
n

R. Grin

JPA

page 343

R. Grin

CONFIG : donne des informations au moment du


dploiement sur la configuration
JPA

page 344

logging (2)
n

FINE : donne des informations sur les ordres


SQL utile pendant les tests et la mise au point

FINER : encore plus dinformations, par exemple


sur les transactions

FINEST : encore plus


l di
dinformations,
f
ti
par

Fichiers XML

exemple sur lutilisation des squences

R. Grin

JPA

page 345

R. Grin

Placement des fichiers XML

JPA

Exemple

Par dfaut les fichiers XML contenant les


mta donnes sont places dans le fichier
META-INF/orm.xml, sous un rpertoire du
classpath
Il est possible dindiquer dautres
emplacements avec le tag <mapping-file>
dans le fichier persistence.xml qui dfinit
lunit de persistance

<persistence-unit name="xxxx">
...
<mapping-file>META-INF/queries.xml
</mapping-file>
<
<mapping-file>META-INF/entities.xml
i
fil >META INF/ titi
l
</mapping-file>
</persistence-unit>

R. Grin

R. Grin

JPA

page 346

page 347

JPA

page 348

58

Fichiers XML annotations

Mta-donnes par dfaut

Avantages des annotations :


n mta donnes proches du code
n pas besoin de donner le contexte comme
dans les fichiers XML
n plus simple
Inconvnients :
n changement des mta donnes ncessite
une recompilation
Les informations donnes dans les fichiers
XML lemportent sur les annotations

Llment <persistence-unit-defaults>
contient des valeurs par dfaut qui sappliquent
toutes les entits de lunit de persistance
Les sous-lments peuvent tre : <schema>
(donner le nom du schma relationnel),
<catalog> (idem <schema> pour les SGBD
qui supportent les catalogues), <access>
(accs pour toutes les classes non annotes),
<cascade-persist> (pour imposer la
persistance par transitivit) et <entitylisteners> (couteurs par dfaut)

R. Grin

R. Grin

JPA

page 349

Fichiers XML annotations

JPA

page 350

Exemple de fichier orm.xml (en-tte)

Les annotations sont le plus souvent utilises


Les fichiers de configuration XML peuvent tre
prfrs lorsque linformation
n est dpendante de lenvironnement
d i ; par exemple
dexcution
l pour lles noms d
de
tables ou de colonnes
n concerne plusieurs classes ; par exemple
@TableGenerator qui donne le nom de la
table qui gnre automatiquement les cls
didentification des entits

R. Grin

JPA

page 351

<?xml version="1.0" encoding="UTF-8" ?>


<entity-mappings
xmlns="http://java.sun.com/xml/ns/persisten
ce.orm"
xmlns:xsi:"http://www
xmlns:xsi:
http://www.w3.org/2001/XMLSchema
w3 org/2001/XMLSchema
-instance"
xsi-schemaLocation =
"http://java.sun.com/xml/ns/persistence.xml
http://java.sun.com/xml/ns/persistence/orm_
1_0.xsd" version="1.0">

R. Grin

JPA

page 352

Exemple de fichier orm.xml (fin)


<entity class="jpa.Employe">
<table name="EMP" />
<named-query name="findEmpByName"
<query>select e from Employe e where
e nom like :nomEmploye</query>
e.nom
</named-query>
</entity>
</entity-mappings>

R. Grin

JPA

page 353

JPA et DAO

R. Grin

JPA

page 354

59

Les DAOs sont encore utiles

Utilit des DAO ?


La possibilit de dtacher et rattacher une
entit rend souvent les DTO inutiles (voir
cours sur DAO et modles de conception
associs)
Puisque JPA augmente fortement la portabilit
du code charg de la persistance, est-ce que
les DAOs sont encore ncessaires ?

R. Grin

JPA

page 355

Pour les petites applications, avec peu de


fonctionnalits mtier , lutilisation directe
de JPA depuis le code mtier, sans utilisation
de DAOs, simplifie le code li la persistance ;
les DAO ne sont alors pas vraiment utiles
Pour les applications plus complexes, les
DAOs peuvent apporter une meilleure
abstraction et une meilleure factorisation du
code li la persistance ; de plus des dtails
techniques lis JPA peuvent tre cachs

R. Grin

Exemple de factorisation du code

R. Grin

R. Grin

JPA

page 357

page 356

Variantes des DAOs

Un DAO peut contenir des mthodes


spcialement adaptes au mtier
Par exemple, une mthode qui renvoie la liste
des candidats qui ont obtenu leur examen
avec une certaine mention, passe en
paramtre
Cette mthode peut tre appele de plusieurs
endroits du code mtier

JPA

Parmi toutes les variantes des mthodes des


DAOs (voir cours sur les DAOs), celles qui
prennent en paramtre ou qui renvoient des
objets (des entits JPA dans ce cas) sont le
plus
l souventt choisies
h i i
En effet, les entits dtaches peuvent jouer
le rle des DTOs qui sont donc inutiles, et les
variantes qui utilisent plusieurs paramtres
dont les valeurs correspondent aux proprits
des objets compliquent inutilement le code
JPA

page 358

DAOs gnriques

Interface DAO gnrique

La gnricit permet dcrire une classe mre


gnrique de tous les DAOs, ce qui allge
dautant les classes filles reprsentant
chacune des classes DAOs
Le type des entits gres et le type de
lidentificateur sont les paramtres de type de
ce DAO gnrique
Les transparents suivants sont un exemple
dimplmentation que vous pouvez modifier
votre convenance

public interface DaoGenerique<T,ID extends


Serializable> {
T findById(ID id);
List<T> findAll();
void create(T objet);
void delete(T entite);
T update(T entite);
}

R. Grin

R. Grin

JPA

page 359

JPA

page 360

60

Interface DAO pour une entit

public interface StyloDao


extends DaoGenerique<Stylo, Long> { }

On peut ajouter des mthodes adapte au


mtier , comme cette mthode qui renvoie
toutes les marques de stylos en vente :
public interface StyloDao
extends DaoGenerique<Stylo, Long> {
List<String> findMarques();
}

R. Grin

JPA

page 361

Classe DAO gnrique (1)


public abstract class
DaoGeneriqueJpa<T, ID extends Serializable>
implements DaoGenerique<T, ID> {
private Class<T> classeEntite;
private EntityManager em;
public
bli DaoGeneriqueJpa()
G
i
() {
// classe concrte de T passe find
this.classeEntite = (Class<T>)
((ParameterizedType)getClass().
.getGenericSuperclass())
.getActualTypeArguments()[0];
}
R. Grin

Classe DAO gnrique (2)

JPA

page 362

Classe DAO gnrique (3)

public void insert(T objet) {


em.persist(objet);
}
public void delete(T objet) {
em.remove(objet);
}
public T findById(ID id) {
return em.find(classeEntite, id);
}
public T update(T entite) {
return em.merge(entite);
}
R. Grin

JPA

public void
setEntityManager(EntityManager em) {
this.em = em;
}
protected EntityManager
getEntityManager() {
return this.em;
}
}

page 363

R. Grin

JPA

page 364

DAO pour une entit


public class StyloDaoJpa extends
DaoGeneriqueJpa<Stylo, Long>
implements StyloDao {
public List<Stylo> findAll() {
Query query = getEntityManager()
.createNamedQuery("Stylo.findAll");
return
(List<Stylo>)query.getResultList();
}

Cache des donnes

}
R. Grin

JPA

page 365

R. Grin

JPA

page 366

61

Utilit

Utilisation des caches

Tous les fournisseurs de persistance utilisent


un cache de second niveau (en plus du
contexte de persistance) pour viter des
accs aux bases de donnes, et donc
amliorer
li
lles performances
f
La spcification JPA ne donne aucune
indication sur les caches de 2me niveau ; il
faut consulter la documentation du
fournisseur de persistance pour connatre les
possibilits

R. Grin

R. Grin

JPA

page 367

Il nest pas toujours facile dutiliser


correctement les caches de 2me niveau
Le plus souvent il est possible dindiquer
quelles classes utiliseront ces caches, et sur
quel mode
Par exemple, il peut tre trs intressant
dutiliser un cache read-only pour des
classes dont les donnes ne changent que
trs rarement comme les noms des pays

Problmes ventuels

page 368

Solutions (1)
Lutilisation de la mthode refresh de
EntityManager permet de rcuprer dans
la base de donnes des donnes
fraiches , sans passer par le cache
Un blocage pessimiste peut parfois tre la
solution si on souhaite interdire la
modification de lignes par une autre
application (implmentation dpendante du
fournisseur de persistance)

Parfois ces caches posent des problmes si


la base de donnes est utilises en parallle
par dautres applications
Par exemple, si des entits lies une entit
sont supprimes de la base en dehors de
lapplication, le cache peut penser modifier
une ligne avec un UPDATE au lieu den
insrer une nouvelle avec un INSERT

R. Grin

R. Grin

JPA

JPA

page 369

JPA

page 370

Solutions (2)

Parfois la seule solution est de vider le cache


ou dindiquer au fournisseur de ne pas utiliser
le cache pour effectuer certaines oprations
(implmentation dpendante du fournisseur
d persistance)
de
i t
)

R. Grin

JPA

page 371

Optimisations

R. Grin

JPA

page 372

62

Les performances dune application peuvent


tre grandement amliores par
n un choix adapt du mode de rcupration
des entits associes
n lutilisation doprations de modifications
en volume, sans cration dentits
me
n une bonne utilisation du cache de 2
niveau

R. Grin

JPA

page 373

Mthode callback et listener

R. Grin

Mthodes callback
Des mthodes peuvent tre annotes pour
indiquer quelles seront appeles par le
fournisseur de persistance quand une entit
passera dans une nouvelle tape de son
cycle de vie
Ces mthodes peuvent appartenir une
classe entit (entity) ou classe mre
mappedSuperclass ou une classe
couteur (listener)
Une mthode peut tre annote par plusieurs
de ces annotations
JPA

page 375

@PrePersist : quand persist (ou merge) sest


termin avec succs
@PostPersist : aprs linsertion dans la BD
@PreRemove : quand remove est appel
@PostRemove : aprs suppression dans la BD
@PreUpdate : avant modification dans la BD
@PostUpdate : aprs modification dans la BD
@PostLoad : aprs la lecture des donnes de
la BD pour construire une entit

R. Grin

Callback dans fichier XML

JPA

page 376

Exemples dutilisation

Les mthodes callback peuvent aussi tre


indiques dans un fichier XML
Un fichier XML peut aussi indiquer des
listeners par dfaut qui seront appeles pour
toutes les entits, dans le sous-lment
<entity-listeners> de llment
<persistence-unit-defaults>

R. Grin

R. Grin

JPA

page 374

Annotations

R. Grin

JPA

page 377

Un trigger de la base de donnes peut


donner les valeurs de lutilisateur qui a
modifi pour la dernire fois une entit, avec
la date de cette modification
Pour remplacer un tel trigger, il est possible
dajouter une mthode annote par
@PrePersist qui remplit ces valeurs dans
les entits
Une mthode callback peut aussi initialiser
des attributs non persistants dune entit
JPA

page 378

63

Callback dans une entit

Callback dans un couteur

Ces mthodes ne doivent aucune paramtre


et le type retour doit tre void
Elles ne doivent pas avoir de clause throws

Si elles renvoient une exception non


contrle,
l lles
ventuelles
ll mthodes
h d
callbacks suivantes ne sont pas appeles et
la transaction est marque pour un rollback
(elle ne pourra pas tre valide)
Une seule mthode callback dun certain type
(par exemple PrePersist) par entit

La signature doit avoir un paramtre


compatible avec le type de lentit gre pour
quil puisse contenir linstance de lentit
Compatible signifie que le type doit tre un
surtype de la classe entit : la classe de
lentit, ou une classe mre, ou une interface
implmente par la classe de lentit
Une classe listener ne doit contenir aucune
variable dinstance (elle doit tre sans tat )
et doit avoir un constructeur sans paramtre

R. Grin

R. Grin

JPA

page 379

JPA

Attacher un couteur

Ordre dappel

Lannotation @EntityListeners permet


dattacher un ou plusieurs couteurs une
classe entit
Exemple :

@Entity
@EntityListeners({C1.class, C2.class})
public class Entite {

R. Grin

JPA

page 380

page 381

Lorsque un vnement du cycle de vie


survient, les diffrentes mthodes sont
appeles dans cet ordre :
1. Mthodes des listeners par dfaut
2. Mthodes des listeners
3. Mthode de lentit en cause

R. Grin

JPA

page 382

Sites Web (1)


Spcification

officielle de JPA :

http://jcp.org/aboutJava/communityprocess/final
/jsr220/index.html (cliquer sur le 1er bouton
download the Specification for evaluation or to
build an application that uses the Specification

Bibliographie

Toplink

http://www.oracle.com/technology/products/ias/t
oplink/jpa/index.html

R. Grin

JPA

page 383

R. Grin

JPA

page 384

64

Sites Web (2)


Hibernate

Livres

http://www.hibernate.org/hib_docs/entitymanag
er/reference/en/html/
Kodo

http://ehtt
//
docs.bea.com/kodo/docs40/full/html/ejb3_overvi
ew.html

R. Grin

JPA

page 385

Pro EJB 3 JPA


de Mike Keith et Merrick Schincariol
Edition Apress
(en anglais)
Java Persistence with Hibernate
de Christian Bauer et Gavin King
Edition Manning
(en anglais)

R. Grin

JPA

page 386

65

Vous aimerez peut-être aussi