Вы находитесь на странице: 1из 17

Langage orienté objet et persistance

En Java, nous manipulons des objets qui sont des instances de classes ; les objets héritent les uns des
autres, peuvent utiliser des collections d'autres objets et, parfois, se désignent eux-mêmes de façon
récursive. Nous disposons de classes concrètes, de classes abstraites, d'interfaces, d'énumérations,
d'annotations, de méthodes, d'attributs, etc.
Cependant, bien que les objets encapsulent soigneusement leur état et leur comportement, cet état n'est
accessible que lorsque la machine virtuelle (JVM) s'exécute : lorsqu'elle s'arrête ou que le ramasse-
miettes nettoie la mémoire, tout disparaît. Ceci dit, certains objets n'ont pas besoin d'être persistants.
Par données persistantes, nous désignons les données qui sont délibérément stockées de façon
permanente sur un support magnétique, une mémoire flash, etc. Un objet est persistant s'il peut stocker
son état afin de pouvoir le réutiliser par la suite.
La sérialisation:
Il existe différent moyens de faire persister l'état en Java. L'un d'eux consiste à utiliser le mécanisme
de sérialisation qui consiste à convertir un objet en une suite de bits : nous pouvons ainsi sérialiser les
objets sur disque, sur une connexion réseau (notamment Internet), sous un format indépendant des
systèmes d'exploitation. Java fournit un mécanisme simple, transparent et standard de sérialisation des
objets via l'implémentation de l'interface java.io.Serializable.
JDBC
Un autre moyen de mémoriser l'état consiste à utiliser JDBC (Java Database Connectivity), qui est
l'API standard pour accéder aux bases de données relationnelles. Nous pouvons ainsi nous connecter à
une base et exécuter des requêtes SQL (Structured Query Language) pour récupérer un résultat. Cette
API fait partie de la plate-forme Java depuis la version 1.1 mais, bien qu'elle soit toujours très utilisée,
elle a tendance à être désormais éclipsée par les outils de correspondance entre modèle objet et modèle
relationnel (ORM, Object-Relational Mapping), plus puissant.

-L'utilisation pour la persistance d'un mapping O/R permet de proposer un niveau d'abstraction plus
élevé que la simple utilisation de JDBC : ce mapping permet d'assurer la transformation d'objets vers
la base de données et vice versa que cela soit pour des lectures ou des mises à jour (création,
modification ou suppression).

-Développée dans le cadre de la version 3.0 des EJB, cette API ne se limite pas aux EJB puisqu'elle
peut aussi être mise en oeuvre dans des applications Java SE.

-L'utilisation de l'API ne requiert aucune ligne de code mettant en oeuvre l'API JDBC.

-L'API propose un langage d'interrogation similaire à SQL mais utilisant des objets plutôt que des
entités relationnelles de la base de données.

-L'API Java Persistence repose sur des entités qui sont de simples POJOs annotés et sur un
gestionnaire de ces entités (EntityManager) qui propose des fonctionnalités pour les manipuler (ajout,
modification suppression, recherche). Ce gestionnaire est responsable de la gestion de l'état des entités
et de leur persistance dans la base de données.

-Comme pour JDBC, l’utilisation de JPA nécessite un fournisseur de persistance qui implémente les
classes et méthodes de l’API

Exemple d'implémentation: Hibernate,EclipseLink...

4INFOB2/3 ZK Page 1
Entité:
Une entité JPA est, par définition, une classe Java annoté par (@Entity) qui doit avoir les propriétés
suivantes :

 Elle doit posséder un constructeur vide, public ou protected. Rappelons que ce constructeur
vide existe par défaut si aucun constructeur n'existe dans la classe. Dans le cas contraire, il
doit être ajouté explicitement.
 Elle ne doit pas être final, et aucune de ses méthodes ne peut être final.
 Une entité JPA ne peut pas être une interface ou une énumération.
 Une entité JPA peut être une classe concrète ou abstraite.
 Si une instance d’entité doit être passée par valeur sous forme d’objet detache(via une
interface distante, par exemple), la classe de l’entité doit implémenté l’interface Serializable.
 Elle doit posséder un attribut qui représente la clé primaire dans la BD (@Id)
 Le fournisseur de persistance accédera à la valeur d’une variable d’instance:

-Soit en accédant directement à la variable d’instance

-Soit en passant par ses accesseurs (getter ou setter)

 Le type d’accès est déterminé par l’emplacement de l'annotation @Id (associées aux
variables d’instance ou aux getter)
 Le choix doit être le même pour toutes les classes d’une hiérarchie d’héritage (interdit de
mélanger les 2 façons)
 En programmation objet il est conseillé d’utiliser plutôt les accesseurs que les accès directs
aux champs (meilleur contrôle des valeurs) ; c’est aussi le cas avec JPA

Rappel : le choix est déterminé par l'emplacement des annotations ; elles sont associées soit
aux accesseurs, soit aux variables d'instance ; ne pas mélanger les 2 !

4INFOB2/3 ZK Page 2
Exemple d'entité:

Mapping
Objet/Relationnel

1-Tout d'abord, la classe est annotée @javax.persistence.Entity, ce qui permet au fournisseur de


persistance de la reconnaître comme une classe persistante et non comme une simple classe POJO.
2. Puis l'annotation @javax.persistence.Id définit l'identifiant unique de l'objet. JPA étant destiné à
associer des objets à des tables relationnelles, les objets doivent posséder un identifiant qui sera
associé à une clé primaire.

A retenir : Une entité doit impérativement posséder un attribut dont la valeur est unique, dit
identificateur unique ou clé primaire. Ce champ permet de différencier chaque objet entité des autres.
Cette clé primaire doit être définie une seule fois dans toute la hiérarchie de l'entité.

Lorsque nous créons une entité, la valeur de cet identifiant peut être produite manuellement par
l'application, ou automatiquement par le fournisseur de persistance si nous précisons l'annotation
@GeneratedValue. Celle-ci peut accepter l'une des quatre valeurs suivantes :

1. IDENTITY : Ce type indique au fournisseur de persistance d'assigner la valeur de la clé primaire en


utilisant la colonne identité de la base de données. Sous MySQL, par exemple, la clé primaire auto-
générée est marquée avec AUTO_INCREMENT

2SEQUENCE : Ce type, comme son nom l'indique, oblige le fournisseur de persistance à utiliser une
séquence de la base de données.

3. TABLE : Ce type demande au fournisseur de persistance de stocker le nom de la séquence et sa


valeur courante dans une table et d'incrémenter cette valeur à chaque fois qu'une nouvelle instance de
l'entité est stockée dans la base.
Configuration « par exception »

La configuration des classes entités suppose des valeurs par défaut

• Il n’est nécessaire d’ajouter des informations de configuration que si ces valeurs par défaut ne
conviennent pas

• Par exemple, @Entity suppose que la table qui contient les données des instances de la classe a le
même nom que la classe

4INFOB2/3 ZK Page 3
Nom de Table:

Pour donner à la table un autre nom que le nom de la classe, il faut ajouter une annotation @Table

Mapping
Objet/Relationnel

Nom de Colonne:

Pour donner à une colonne de la table un autre nom que le nom de l’attribut correspondant, il faut
ajouter une annotation @Column

Mapping
Objet/Relationnel

Classe Embeddable

Les entités persistantes ne sont pas les seules classes persistantes.

Il existe aussi des classes « insérées » ou « incorporées » (embedded) dont les données n’ont pas
d’identité dans la BD mais sont insérées dans une des tables associées à une entité persistante

-Elles peuvent être annotées comme les entités (avec @Column par exemple)

- Par exemple, une classe Adresse dont les valeurs sont insérées dans la table Employe

-Comme les entités, ces classes doivent avoir un constructeur sans paramètre

-Les types permis pour leurs attributs sont les mêmes que les types permis pour les attributs des
entités.

4INFOB2/3 ZK Page 4
Clé composite:

Pas recommandé, mais une clé primaire peut être composée de plusieurs colonnes

• Peut arriver quand la BD existe déjà ou quand la classe correspond à une table association
(association M:N avec information )

• 2 possibilités :

-@IdClass

-@EmbeddedId et @Embeddable

Dans les 2 cas, la clé primaire doit être représentée par une classe Java dont les attributs correspondent
aux composants de la clé primaire

• La classe doit être public, posséder un constructeur sans paramètre, être sérialisable et redéfinir
equals et hashcode.

IdClass

-@IdClass correspond au cas où la classe entité comprend plusieurs attributs annotés par @Id

La classe entité est annotée par @IdClass qui prend en paramètre le nom de la classe clé primaire

-La classe clé primaire n’est pas annotée (comme @Embeddable) ; ses attributs ont les mêmes noms et
mêmes types que les attributs annotés @Id dans la classe entité

EmbeddedId:

@EmbeddedId correspond au cas où la classe entité comprend un


seul attribut annoté @EmbeddedId

• La classe clé primaire est annoté par @Embeddable

4INFOB2/3 ZK Page 5
Associations
-Il s'avère qu'une entité ne travaille généralement pas seule mais qu'elle est reliée à d'autres entités. On
parle de relations entre entités. Cela correspond, bien entendu, à une base de données relationnelle où
les tables sont effectivement en relations les unes avec les autres.
-Une relation possède une direction. Elle peut être unidirectionnelle (un objet peut utiliser un autre
objet) ou bidirectionnelle (un objet peut
interroger un autre objet et vice versa). En Java, nous utilisons le point (.) pour naviguer entre les
objets. Ainsi, lorsque nous écrivons, par
exemple :
client.getAdresse().getPays();
nous navigons d'un objet de type Client vers un objet de type Adresse puis vers un objet de type Pays.

Relations dans la base de données relationnelles

-Dans le monde relationnel, les choses sont différentes puisque, à proprement parler, une base de
données relationnelle est un ensemble de relations (également appelées tables) : tout est modélisé sous
forme de table - pour modéliser une relation, vous ne disposez ni de listes, ni d'ensembles, ni de cartes
: vous ne possédez que des tables.
-Ainsi, une relation entre deux classes Java sera représentée dans la base de données par une référence
à une table qui peut être modélisée de deux façons :
1. Avec une clé étrangère (une colonne de jointure) : A titre d'exemple, supposons qu'un client n'ait
qu'une seule adresse, En Java, la classe Client aurait donc un attribut Adresse ; dans le monde
relationnel, vous pourriez avoir ainsi une table Client pointant vers une table Adresse via la clé
étrangère

2. Avec une table de jointure : la seconde méthode consiste à utiliser une table de jointure. Ainsi, la
table Client ne stocke plus la clé étrangère vers Adresse mais utilise une table intermédiaire pour
représenter la relation liant ces deux tables. Cette relation est constituée par les clés primaires des deux
tables.

Remarque:
Nous n'utilisons jamais de table de jointure pour représenter une relation 1-1 ou N-1 car cela pourrait
avoir des conséquences sur les performances (il faudrait effectivement toujours accéder à la troisième
table pour obtenir l'adresse d'un client) ; elles sont généralement réservées aux relations 1-N
(unidirectionelle) ou N-M.

4INFOB2/3 ZK Page 6
Relations entre entités:

La plupart des entités doivent pouvoir référencer ou être en relation avec d'autres entités. JPA permet
d'associer ces relations de sorte qu'une entité puisse être liée à une autre dans un modèle relationnel.
Les annotations correspondantes aux cardinalités d'une relation entre deux entités sont les suivantes,
en sachant que chacune d'elles peut être utilisée de façon unidirectionnelle ou bidirectionnelle :
1-1 : @OneToOne,
1-N : @OneToMany,
N-1 : @ManyToOne,
N-M : @ManyToMany.

Bout propriétaire:

Pour les associations autres que M:N ce bout correspond à la table qui contient la clé étrangère qui
traduit l’association

Pour les associations M:N le développeur peut choisir arbitrairement le bout propriétaire

L’autre bout (non propriétaire) est qualifié par l’attribut mappedBy qui donne le nom de l’attribut
dans le bout propriétaire qui correspond à la même association.

Association M:1 bidirectionnelle :

Représentée par une clé étrangère dans la table qui correspond au côté propriétaire (obligatoirement le
côté « Many »)

1. L'entité Departement utilise mappedBy de son annotation @OneToMany. Ici, mappedBy indique
que la colonne de jointure (departement) est déclarée à l'autre extrémité de la relation.
2. De son côté, l'entité Employee définit la colonne de jointure avec l'annotation @JoinColumn et
renomme la clé étrangère en id_departement.
3. Employee est l'extrémité propriétaire de le relation et, en tant que telle, est la seule à définir
l'association de la colonne de jointure.
4. Departement est l'extrémité opposée et c'est donc la table de l'entité propriétaire qui contient la clé
étrangère (la table t_employee possède bien une colonne id_departement).

4INFOB2/3 ZK Page 7
Remarque

Il existe un élément mappedBy pour les annotations @OneToOne, @OneToMany et @ManyToMany,


mais pas pour @ManyToOne.

Association 1:N unidirectionnelle :


Dans une relation 1-N, l'entité source référence un ensemble d'entités cibles. Une commande, par
exemple, est composée d'un ensemble d'articles

Les relations 1-N unidirectionnelles utilisent une table de jointure pour représenter la relation. Cette
table est une liste de couples de clés étrangères : une clé fait référence à la table COMMANDE avec le
même type que sa clé primaire, l'autre désigne la table ARTICLE. Cette table de jointure s'appelle par
défaut COMMANDE_ARTICLE.

Association M:N :
Une relation N-M bidirectionnelle intervient lorsqu'un objet source fait référence à plusieurs cibles et
qu'une cible fait elle-même référence à plusieurs sources. Un Employee par exemple, est affectée à
plusieurs Pojets, et un même projet peut être développer par plusieurs employees.
1. Côté Java, chaque entité contiendra donc une collection d'entités cibles.
2. En terme de base de données relationnelle, la seule façon de représenter une relation N-M consiste à
utiliser, bien entendu, une table de jointure (une colonne de jointure ne peut pas convenir) ; comme
nous l'avons évoqué précédemment, il est également nécessaire de définir
explicitement le propriétaire d'une relation bidirectionnelle à l'aide de l'élément mappedBy.

4INFOB2/3 ZK Page 8
-Les valeurs par défaut : o le nom
de la table association est la concaténation des 2 tables, séparées par « _ »

-les noms des colonnes clés étrangères sont les concaténations de la table référencée, de « _ » et de la
colonne « Id » de la table référencée

-Le côté propriétaire est arbitraire

-Si les valeurs par défaut ne conviennent pas, le côté propriétaire doit comporter une annotation
@JoinTable

-L’autre côté doit toujours comporter l’attribut mappedBy

@JoinTable

-Donne des informations sur la table association qui va représenter l’association:

• Attribut name donne le nom de la table

• Attribut joinColumns donne les noms des colonnes de la table qui référencent les clés
primaires du côté propriétaire de l’association

• Attribut inverseJoinColumns donne les noms des colonnes de la table qui référencent les
clés primaires du côté qui n’est pas propriétaire de l’association

4INFOB2/3 ZK Page 9
Association M:N avec information portée par l'association :

-Une association M:N peut porter une information.

• Exemple :

-Association entre les développeurs et les projets: Un développeur a une 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 décrit.

-L'association sera traduite par une classe association.

4INFOB2/3 ZK Page 10
Récapitulatif:

Classe propriétaire

4INFOB2/3 ZK Page 11
Héritage:
Nous venons de voir que les relations entre entités ont des équivalents directs dans les bases de
données. Ce n'est pas le cas avec l'héritage car ce concept est totalement inconnu du modèle
relationnel. Il impose donc plusieurs contorsions pour être traduit dans un SGBDR.
Pour représenter un modèle hiérarchique dans un modèle relationnel plat, JPA propose alors trois
stratégies possibles :
1. Une seule table unique pour l'ensemble de la hiérarchie des classes. L'ensemble des attributs de
toute la hiérarchie des entités est mis à plat et regroupé dans une seule table (il s'agit d'ailleurs de la
stratégie par défaut).

2. Une table pour chaque classe concrète. Chaque entité concrète de la hiérarchie est associée à une
table.

3. Jointure entre sous-classes. Dans cette approche, chaque entité de la hiérarchie, concrète ou
abstraite, est associée à sa propre table. Ainsi, nous obtenons dans ce cas là une séparation des attributs
spécifiques de la classe fille par rapport à ceux de la classe parente. Il existe alors, une table pour
chaque classe fille, plus une table pour la classe parente. Une jonction est alors nécessaire pour
instancier la classe fille.

Le support de la stratégie une table pour chaque classe concrète est encore facultatif avec JPA 2.0.
Les applications portables doivent donc l'éviter tant que ce support n'a pas été officiellement déclaré
comme obligatoire dans toutes les implémentations.

1-Une seule table:

La colonne discriminante, s'appelle DTYPE, par défaut, elle est de type String (traduit en VARCHAR
avec une taille par défaut de 31) et elle contient tout simplement le nom de l'entité (ce qui offre une
grande lisibilité au niveau de la table).
Si ce comportement par défaut ne vous convient pas, il est tout-à-fait possible d'utiliser l'annotation
@DiscriminatorColumn pour modifier le nom cette colonne et @DiscriminatorValue pour modifier la
valeur de cette colonne

4INFOB2/3 ZK Page 12
Le gestionnaire d’entités:
-Le gestionnaire d’entités (EntityManager) est une composante essentielle de JPA. JPA gère l’état et le
cycle de vie des entités et les interroge dans un contexte de persistance. C’est également lui qui est
responsable de la création et de la suppression des instances d’entités persistantes et qui les retrouve a
partir de leur clé primaire.
-Lorsqu'un gestionnaire d’entités obtient une référence a une entité, celle-ci est dite gérée. Avant cela,
elle n’était considérée que comme un POJO classique (elle était détachée). L’avantage de JPA est que
les entités peuvent être utilisées comme des objets normaux par différentes couches de l’application et
devenir gérées par le gestionnaire d’entités lorsqu'il faut charger ou insérer des données dans la base.
-Lorsqu'une entité est gérée, il devient possible d’effectuer des opérations de persistance : le
gestionnaire d’entités synchronisera automatiquement l’état de l’entité avec la base de données. -
Lorsqu'une entité est détachée (non gérée), elle redevient un simple POJO et peut être utilisée par les
autres couches (une couche de présentation JSF, par exemple) sans que son état ne soit synchronise
avec la base.
-L’interface javax.persistence.EntityManager est implémentée par un fournisseur de persistance qui
produira et exécutera des instructions SQL.
Obtenir un gestionnaire d’entités

Le gestionnaire d’entités est l’interface centrale pour interagir avec les entités, mais
l’application doit d’abord en obtenir un.
la méthode la plus classique pour obtenir un gestionnaire d’entités consiste à utiliser l’annotation
@PersistenceContext pour en injecter un.

Remarque
Un composant qui s’exécute dans un conteneur (servlet, EJB, service web, etc.) n’a en revanche pas
besoin de créer ou de fermer le gestionnaire d’entités puisque son cycle de vie est gère par le
conteneur

4INFOB2/3 ZK Page 13
La figure suivante montre le code d’une session sans état dans laquelle on injecte une référence à
l’unité de persistance . On injecte dans le GestionEmployee une référence a un EntityManager associe
a l’unité de persistance gestion-employee-ejb. Celle-ci doit définir la source de données a laquelle se
connecter(jta-data-source )

-Il est nécessaire d’indiquer au fournisseur de persistance comment il peut se connecter à la base de
données

- Les informations doivent être données dans un fichier persistence.xml situé dans un répertoire
META-INF dans le classpath.

jta-data-source: pointe vers le nom JNDI de la data source qui englobe la connexion à la base de
données

Contexte de persistance:

-le contexte de persistance, est l’ensemble des instances d’entités gérées a un instant donne.
Dans un contexte de persistance, il ne peut exister qu'une seule instance d’entité avec le même
identifiant de persistance – si, par exemple, une instance de Employee ayant l’identifiant 1234
existe dans le contexte de persistance, aucun autre employee portant cet identifiant ne peut
exister dans le même contexte. Seules les entités contenues dans le contexte de persistance
sont gérées par le gestionnaire d’entités – leurs modifications seront reflétées dans la base de
données.
-Le gestionnaire d’entités modifie ou consulte le contexte de persistance a chaque
appel d’une méthode de l’interface javax.persistence.EntityManager. Lorsque la méthode
persist() est appelée, par exemple, l’entité passée en paramètre sera ajoutée au contexte de
persistance si elle ne s’y trouve pas déjà. De même, lorsque l’on recherche une entité a partir
de son identifiant, le gestionnaire d’entités vérifie d’abord si elle existe déjà dans le contexte
de persistance. Ce contexte peut donc être considéré comme un cache de premier niveau :
c’est un espace réduit ou le gestionnaire stocke les entités avant d’écrire son contenu dans la
base de données.

4INFOB2/3 ZK Page 14
Les objets ne vivent dans le contexte de persistance que le temps de la transaction.

Rappel:

-L’unité de persistance est le pont qui relie le contexte de persistance et la base de données
C’est une configuration nommée qui contient les informations nécessaires à l’utilisation d’une base de
données.

Elle est associée à un ensemble de classes entités

-Les informations sur une unité de persistance sont données dans un fichier persistence.xml situé dans
un sous répertoire META-INF d’un des répertoires du répertoire META d’un classpath

Manipulation des entités

Méthodes de l’interface EntityManager pour manipuler les entités

Méthode Description
void persist(Object entity) Cree une instance gérée et persistante
<T> T find(Class<T> entityClass, Recherche une entité de la classe et de la clé
Object primaryKey) indiquées.
void remove(Object entity) Supprime l’instance d’entité du contexte de
persistance et de la base de données.
<T> T merge(T entity) Fusionne l’état de l’entité indiquée dans le
contexte de persistance courant
void refresh(Object entity Rafraichit l’état de l’instance a partir de la
base de données en écrasant les éventuelles
modifications apportées a l’entité
void flush() Synchronise le contexte de persistance avec
la base de données.
void clear() Vide le contexte de persistance. Toutes les
entités gérées deviennent détachées
void clear(Object entity) Supprime l’entité indiquée du contexte de
persistance
boolean contains(Object entity) Teste si l’instance est une entité gérée
appartenant au contexte de persistance
courant

Cycle de vie d’une instance d’entité:

L’instance peut être:

 nouvelle (new) : elle est créée mais pas associée à un contexte de persistance
 gérée (managed) par un gestionnaire de persistance elle a une identité dans la base de
données (un objet peut devenir géré par la méthode persist, ou merge d’une entité détachée ;
un objet géré peut aussi provenir d’une requête faite par un gestionnaire d’entités ou d’une
navigation à partir d’un objet géré)

4INFOB2/3 ZK Page 15
 détachée (detached) : elle a une identité dans la base mais elle n’est plus associée à un
contexte de persistance (une entité peut, par exemple, devenir détachée si le contexte de
persistance est vidé ou si elle est envoyée dans une autre JVM par RMI)
 supprimée (removed): elle a une identité dans la base ; elle est associée à un contexte de
persistance et ce contexte doit la supprimer de la base de données (passe dans cet état par la
méthode remove)

Chargement des relations


Toutes les annotations que nous venons de découvrir (@OneToOne, @OneToMany, @ManyToOne et
@ManyToMany) définissent un attribut de chargement qui précise que les objets associés doivent être
chargés immédiatement (chargement "glouton") ou plus tard (chargement "paresseux") et qui influe
donc sur les performances.
Vous pouvez optimiser les performances en chargeant les données de la base lors de la première
lecture de l'entité (glouton) ou uniquement lorsqu'elle est utilisée (paresseux).
Chaque annotation possède une stratégie de chargement par défaut que nous devons connaître et qu'il
est souhaitable de pouvoir modifier si cela ne convient pas. Nous pouvons donc changer ce
comportement au travers du paramètre fetch qui peut prendre les deux valeurs : LAZY (paresseux) ou
EAGER (glouton).
Stratégie de chargement par défaut
@OneToOne EAGER

@ManyToOne EAGER

@OneToMany LAZY

@ManyToMany LAZY

1. EAGER placera toutes les données en mémoire à l'aide d'un petit nombre d'accès à la base (le
fournisseur de persistance utilisera sûrement des jointures pour extraire ces données).

4INFOB2/3 ZK Page 16
2. Avec LAZY, vous ne risquez plus de remplir la mémoire puisque vous contrôlez les objets qui
seront chargés, mais vous devrez faire plus d'accès à la base à chaque fois.
Le paramètre fetch est finalement très important car, mal utilisé, il peut pénaliser les performances.

(Répercutions des événements) Les opérations en cascade


-Par défaut, chaque opération du gestionnaire d'entités ne s'applique qu'à l'entité passée en paramètre à
l'opération. Parfois, cependant, nous désirons propager son action à ses relations - c'est ce que nous
appelons répercuter un événement, ou encore opérations en cascade.
seule fois. Ces opérations sont regroupées dans l'énumération CascadeType :
1. CascadeType.PERSIST : Propage les opérations persist() à la cible de la relation.
2. CascadeType.MERGE : Propage les opérations merge() à la cible de la relation.
3. CascadeType.REMOVE : Propage les opérations remove() à la cible de la relation.
4. CascadeType.REFRESH : Propage les opérations refresh() à la cible de la relation.
5. CascadeType.CLEAR : Propage les opérations clear() à la cible de la relation.
6. CascadeType.ALL : Propage toutes les opérations précédentes.

L'utilisation du mécanisme de cascade est une réelle simplification pour le développeur. En effet, il n'a
plus à gérer les boucles de suppression, de modification... Toutefois, cet outil doit être utilisé
judicieusement et avec parcimonie. En effet, une utilisation trop importante de ce mécanisme peut
très vite nuire aux performances de l'application.

Exemple

@OneToMany( cascade=CascadeType.PERSIST)

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

4INFOB2/3 ZK Page 17

Вам также может понравиться