4
Gestion des objets persistants
L’API de persistance de Java, JPA, a deux aspects. Le premier est la possibilité d’as-
socier des objets à une base de données relationnelle. La conguration par exception
permet aux fournisseurs de persistance de faire l’essentiel du travail sans devoir
ajouter beaucoup de code, mais la richesse de JPA tient également à la possibilité
d’adapter ces associations à l’aide d’annotations ou de descriptions XML. Que ce
soit une modication simple (changer le nom d’une colonne, par exemple) ou une
adaptation plus complexe (pour traduire l’héritage), JPA offre un large spectre de
possibilités. Vous pouvez donc associer quasiment n’importe quel modèle objet à
une base de données existante.
Le second aspect concerne l’interrogation de ces objets une fois qu’ils ont été
associés à une base. Élément central de JPA, le gestionnaire d’entités permet de
manipuler de façon standard les instances des entités. Il fournit une API pour créer,
rechercher, supprimer et synchroniser les objets avec la base de données et permet
d’exécuter différentes sortes de requêtes JPQL sur les entités, comme des requêtes
dynamiques, statiques ou natives. Le gestionnaire d’entités autorise également la
mise en place de mécanismes de verrouillage sur les données.
Le monde des bases de données relationnelles repose sur SQL (Structured Query
Language). Ce langage de programmation a été conçu pour faciliter la gestion des
données relationnelles (récupération, insertion, mise à jour et suppression), et sa
syntaxe est orientée vers la manipulation de tables. Vous pouvez ainsi sélection-
ner des colonnes de tables constituées de lignes, joindre des tables, combiner les
résultats de deux requêtes SQL à l’aide d’une union, etc. Ici, il n’y a pas d’objets
mais uniquement des lignes, des colonnes et des tables. Dans le monde Java,
l’on manipule des objets, un langage conçu pour les tables (SQL) doit être un peu
déformé pour convenir à un langage à objets (Java). C’est là que JPQL (Java Persis-
tence Query Language) entre en jeu.
© 2010 Pearson Education France – Java EE 6 et GlassFish 3 – Antonio Goncalves
142 Java EE 6 et GlassFish 3
JPQL est le langage qu’utilise JPA pour interroger les entités stockées dans une base
de données relationnelle. Sa syntaxe ressemble à celle de SQL mais opère sur des
objets entités au lieu d’agir directement sur les tables. JPQL ne voit pas la structure
de la base de données sous-jacente et ne manipule ni les tables ni les colonnes
uniquement des objets et des attributs. Il utilise pour cela la notation pointée que
connaissent bien tous les développeurs Java.
Dans ce chapitre, nous verrons comment gérer les objets persistants. Nous appren-
drons comment réaliser les opérations CRUD (Create, Read, Update et Delete) avec
le gestionnaire d’entités et créerons des requêtes complexes en JPQL. La n du
chapitre expliquera comment JPA gère la concurrence d’accès aux données.
Interrogation d’une entité
Comme premier exemple, étudions une requête simple: trouver un livre par son
identiant. Le Listing4.1 présente une entité Book utilisant l’annotation @Id pour
informer le fournisseur de persistance que l’attribut id doit être associé à une clé
primaire.
Listing4.1: Entité Book simple
@Entity
public class Book {
@Id
private Long id;
private String title;
private Float price;
private String description;
private String isbn;
private Integer nbOfPage;
private Boolean illustrations;
// Constructeurs, getters, setters
}
L’entité Book contient les informations pour l’association. Ici, elle utilise la plupart
des valeurs par défaut: les données seront donc stockées dans une table portant le
même nom que l’entité (BOOK) et chaque attribut sera associé à une colonne homo-
nyme. Nous pouvons maintenant utiliser une classe Main distincte (voir Listing4.2)
qui utilise l’interface javax.persistence.EntityManager pour stocker une instance
de Book dans la table.
© 2010 Pearson Education France – Java EE 6 et GlassFish 3 – Antonio Goncalves
Chapitre 4
Gestion des objets persistants
143
Listing4.2: Classe Main pour stocker et récupérer une entité Book
public class Main {
public static void main(String[] args) {
// 1-Création d’une instance de l’entité Book.
Book book = new Book();
book.setId(1234L);
book.setTitle("The Hitchhiker’s Guide to the Galaxy");
book.setPrice(12.5F);
book.setDescription("Science fiction by Douglas Adams.");
book.setIsbn("1-84023-742-2");
book.setNbOfPage(354);
book.setIllustrations(false);
// 2- Création d’un gestionnaire d’entités et d’une
// transaction.
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("chapter04PU");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
// 3-Stockage du livre dans la base de données.
tx.begin();
em.persist(book);
tx.commit();
// 4-Récupération du livre par son identifiant.
book = em.find(Book.class, 1234L);
System.out.println(book);
em.close();
emf.close();
}
}
La classe Main du Listing4.2 utilise quatre étapes pour stocker un livre dans la base
de données puis le récupérer.
1. Création d’une instance de l’entité Book. Les entités sont des POJO gérés par
le fournisseur de persistance. Du point de vue de Java, une instance de classe
doit être créée avec le mot-clé new, comme n’importe quel POJO. Il faut bien
insister sur le fait qu’à ce stade le fournisseur de persistance ne connaît pas
encore l’objet Book.
2. Création d’un gestionnaire d’entités et d’une transaction. C’est la partie
importante du code car on a besoin d’un gestionnaire d’entités pour les manipu-
ler. On crée donc d’abord une fabrique de gestionnaires d’entités pour l’unité de
© 2010 Pearson Education France – Java EE 6 et GlassFish 3 – Antonio Goncalves
144 Java EE 6 et GlassFish 3
persistance chapter04PU. Cette fabrique sert ensuite à fournir un gestionnaire
(la variable em) qui permettra de créer une transaction (la variable tx), puis à
stocker et à récupérer un objet Book.
3. Stockage du livre dans la base de données. Le code lance une transaction
(tx.begin()) et utilise la méthode EntityManager.persist() pour insérer une
instance de Book. Lorsque la transaction est validée (tx.commit()), les données
sont écrites dans la base de données.
4. Récupération d’un livre par son identiant. Là encore, on utilise le gestion-
naire d’entités an de retrouver un livre à partir de son identiant à l’aide de la
méthode EntityManager.find().
Vous remarquerez que ce code ne contient aucune requête SQL ou JPQL ni d’appels
JDBC. La Figure 4.1 montre l’interaction entre ces composants. La classe Main
interagit avec la base de données sous-jacente via l’interface EntityManager, qui
fournit un ensemble de méthodes standard permettant de réaliser des opérations sur
l’entité Book. En coulisse, cet EntityManager utilise le fournisseur de persistance
pour interagir avec la base de données. Lorsque l’on appelle l’une des méthodes de
l’EntityManager, le fournisseur de persistance produit et exécute une instruction
SQL via le pilote JDBC correspondant.
SQL / JDBC
Main
Base de
données
<<Interface>>
EntityManager
+persist(entity : Object) : void
+find(entityClass, : Class<T>, primaryKey : Object) : <T>
Book
-id : Long
-title : String
-price : Float
-description : String
-nbOfPage : Integer
-illustrations : Boolean
Figure4.1
Le gestionnaire d’entités interagit avec l’entité et la base de données sous-jacente.
Quel pilote JDBC utiliser? Comment se connecter à la base? Quel est le nom de la
base? Toutes ces informations sont absentes du code précédent. Lorsque la classe
Main crée une fabrique EntityManagerFactory, elle lui passe le nom d’une unité de
persistance en paramètre chapter04PU ici. Cette unité de persistance indique au
gestionnaire d’entités le type de la base à utiliser et les paramètres de connexion:
© 2010 Pearson Education France – Java EE 6 et GlassFish 3 – Antonio Goncalves
Chapitre 4
Gestion des objets persistants
145
toutes ces informations sont précisées dans le chier persistence.xml (voir Lis-
ting4.3) qui doit être déployé avec les classes.
Listing4.3: Le chier persistence.xml dénit l’unité de persistance
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="chapter04PU"
transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider
</provider>
<class>com.apress.javaee6.chapter04.Book</class>
<properties>
<property name="eclipselink.target-database" value="DERBY"/>
<property name="eclipselink.jdbc.driver"
value= "org.apache.derby.jdbc.ClientDriver"/>
<property name="eclipselink.jdbc.url"
value="jdbc:derby://localhost:1527/chapter04DB"/>
<property name="eclipselink.jdbc.user" value="APP"/>
<property name="eclipselink.jdbc.password" value="APP"/>
</properties>
</persistence-unit>
</persistence>
L’unité de persistance chapter04PU dénit une connexion JDBC pour la base de
données Derby nommée chapter04DB. Elle se connecte à cette base sous le compte
utilisateur APP avec le mot de passe APP. Le marqueur <class> demande au fournisseur
de persistance de gérer la classe Book.
Pour que ce code fonctionne, le SGBDR Derby doit s’exécuter sur le port 1527 et
les classes Book et Main doivent avoir été compilées et déployées avec ce chier
META-INF/persistence.xml. Si vous avez actila trace d’exécution, vous verrez
apparaître quelques instructions SQL mais, grâce à l’API d’EntityManager, votre
code manipule des objets de façon orientée objet, sans instruction SQL ni appel
JDBC.
Le gestionnaire d’entités
Le gestionnaire d’entités 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 égale-
ment lui qui est responsable de la création et de la suppression des instances d’enti-
tés persistantes et qui les retrouve à partir de leur clé primaire. Il peut les verrouiller
© 2010 Pearson Education France – Java EE 6 et GlassFish 3 – Antonio Goncalves
1 / 10 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !