2. Création de l'environnement technique

2.1. Introduction

L'ensemble des opérations montrées ici sont réalisées sous NetBeans 6.9.1. Si l'on veut suivre la construction de ce premier projet pas à pas, c'est cet IDE qu'il faut utiliser.

2.2. Création de la base Derby

Commençons tout d'abord par créer une base de données. Nous allons utiliser Derby, intégré à NetBeans. On pourrait tout à fait utiliser une base MySQL ou Postgres, cela reviendrait au même. La première étape consiste donc à créer une base Derby "JPA_Test" et à s'y connecter. NetBeans demande également un nom d'utilisateur et un mot de passe, qu'il utilise pour créer cette base.
Création de la base Derby

Figure 1. Création de la base Derby


La deuxième étape consiste à se connecter à cette base Derby. Pour cela, il suffit de cliquer sur l'option "Connexion..." du menu.
Connexion à la base Derby

Figure 2. Connexion à la base Derby


Notre base Derby est à présent prête à fonctionner.

2.3. Création du projet NetBeans et d'une première entité

Le projet NetBeans est un projet Java normal. Effectivement, une classe JPA est une classe Java normale. En particulier elle n'a pas besoin de vivre dans un projet JEE. On crée donc un projet NetBeans de façon classique. Dans le jargon JPA, une classe "persistante", est aussi appelée une "entité". Ce terme n'est pas à confondre avec la terminologie UML. Une "entité" JPA est une classe Java normale, annotée comme nous allons le voir. Créons à présent une première entité JPA.
Création d'une première entité JPA

Figure 3. Création d'une première entité JPA


NetBeans nous pose alors une série de questions, qui vont lui permettre de configurer JPA pour nous. La première de ces questions est le type Java utilisé pour coder la clé primaire de notre entité. Cette entité va être associée à des lignes dans une table d'une base de données. Chacune de ces lignes doit posséder une clé primaire. Cette clé primaire sera associée à un champ de notre classe. Le type par défaut Long nous convient, n'y touchons pas.
Création de l'entité Marin

Figure 4. Création de l'entité Marin


La deuxième étape nous pose quatre questions :
  • Le nom de notre persistence unit (unité de persistance). Une unité de persistance est un ensemble de classes persistantes regroupées entre elles, et associées à une même base de données. En général, une application ne manipule qu'une seule unité de persistance à la fois. Chaque unité de persistance doit porter un nom, on choisit ici "jpa-test".
  • L'implémentation de JPA utilisée. C'est ici que l'on peut choisir d'utiliser Hibernate, OpenJPA ou EclipseLink. C'est ce dernier choix que l'on fait ici. Choisir une autre implémentation n'a qu'un impact limité dans le contexte de ce cours. Dans une application en production, il est souvent déterminant.
  • La connexion à la base de données utilisée par cette unité de persistance. Cette connexion va être utilisée par l'implémentation pour valider le schéma, éventuellement le créer, et surtout faire toutes les lectures / écritures sur la base de données. Ici l'on choisit la base Derby que l'on vient de créer.
  • Enfin, le dernier paramètre à fixer décide de la stratégie de génération du schéma de tables que notre unité de persistance va utiliser. Cette stratégie s'applique au lancement de notre application. Trois options sont offertes. L'option create permet de créer les tables si elles n'existent pas déjà. L'option drop and create efface le contenu du schéma systématiquement à chaque lancement. Cette option n'est utilisable qu'en phase de développement et de test, et uniquement si notre modèle ne comporte pas trop d'entités, ni trop de tables. Enfin, l'option none ne fait rien. On choisit dans cet exemple l'option drop and create.
Choix de la base et de l'implémentation

Figure 5. Choix de la base et de l'implémentation


Examinons à présent les différents éléments que NetBeans a créés pour nous.

2.4. Structure d'un projet persistant

Un projet persistant est composé de trois éléments :
  • Un jeu de classes persistantes, ici nous n'en avons qu'une : Marin.
  • Un descripteur d'unité de persistances : il s'agit d'un fichier persistence.xml, rangé dans le répertoire META-INF du projet.
  • Les JAR contenant les annotations JPA, et l'implémentation choisie. Ici il s'agit des JARs eclipselink-javax.persistence-2.0.jar et eclipselink-2.0.2.jar respectivement.
Structure du projet NetBeans

Figure 6. Structure du projet NetBeans


Il manque toutefois un élément à ce projet, que NetBeans ne nous donne pas automatiquement : le pilote JDBC de Derby. Pour que notre configuration soit complète, il faut ajouter le JAR de ce pilote aux librairies de notre projet.

2.5. Une première classe persistante

Notre première classe persistante est la classe Marin. Examinons le code que NetBeans a généré pour nous.

Exemple 1. Une première classe persistante

@Entity
 public  class Marin  implements Serializable {

     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;
    
     public Long getId() {
         return id;
    }

     public  void setId(Long id) {
         this.id = id;
    }
    
     // suivent les méthode toString(), equals() et hashCode()
 }

On remarque tout d'abord la présence de trois éléments nouveaux : @Entity, @Id et @GeneratedValue. Ces éléments, qui commencent par le caractère @ sont des annotations. D'une façon générale, une annotation est une information que l'on donne à la machine Java sur le fonctionnement de l'élément annoté. Par exemple, @Entity placé sur un nom de classe indique à la machine Java que cette classe est une classe persistante, et qu'elle doit être associée à une ou plusieurs tables de la base de données. L'annotation @Id indique que ce champ est la clé primaire pour la classe Marin. Comme c'est la base de données qui génère elle-même les valeurs des différentes clés primaires, nous lui indiquons juste une stratégie de génération, par l'annotation supplémentaire @GeneratedValue(strategy = GenerationType.AUTO).

2.6. Un premier fichier persistence.xml

Toute application JPA doit comporter au moins un fichier persistence.xml. C'est dans ce fichier que se trouvent tous les éléments qui permettent de créer les unités de persistance , dont nous allons nous servir pour utiliser notre application. Examinons le contenu de ce fichier.

Exemple 2. Un premier persistence.xml

<persistence  version="2.0" 
              xmlns="http://java.sun.com/xml/ns/persistence"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
                                 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

   <persistence-unit  name="jpa-test"  transaction-type="RESOURCE_LOCAL">

     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

     <class>org.paumard.cours.model.Marin</class>

     <properties>
       <property  name="javax.persistence.jdbc.url"  value="jdbc:derby::1527/JPA_Test"/>
       <property  name="javax.persistence.jdbc.password"  value="jpa_passwd"/>
       <property  name="javax.persistence.jdbc.driver"  value="org.apache.derby.jdbc.ClientDriver"/>
       <property  name="javax.persistence.jdbc.user"  value="jpa_user"/>
       <property  name="eclipselink.ddl-generation"  value="drop-and-create-tables"/>
     </properties>

   </persistence-unit>
  
 </persistence>

Tout d'abord, l'élément racine de ce fichier est persistence. Cet élément peut comporter autant de sous-éléments persistence-unit que l'on veut. Cela dit, généralement on n'en trouve qu'une seule. Chaque élément persistence-unit définit une unité de persistance. Il doit porter un nom (attribut name), et un attribut transaction-type, qui peut prendre deux valeurs : RESOURCE_LOCAL comme ici, ou JTA. Cet élément persistence-unit doit comporter un unique sous-élément provider. C'est cet élément qui définit l'implémentation JPA utilisée. Ici, il s'agit d'EclipseLink. Suit la liste des classes persistantes. Cet élément est en fait facultatif. Enfin, se trouve une liste de propriétés, qui vont permettre à l'unité de persistance de fonctionner. Les premières propriétés de notre exemple sont standard, et permettent à l'unité de persistance d'ouvrir une connexion JDBC vers la base que nous avons définie. La propriété eclipselink.ddl-generation est propre à EclipseLink, et définit le comportement lors du lancement de l'application.
JPA & EJB
Retour au blog Java le soir
Cours & Tutoriaux
Table des matières
Introduction
1. Objet du mapping objet / relationnel
2. Un peu d'histoire
Un premier exemple
1. Introduction
2. Création de l'environnement technique
2.1. Introduction
2.2. Création de la base Derby
2.3. Création du projet NetBeans et d'une première entité
2.4. Structure d'un projet persistant
2.5. Une première classe persistante
2.6. Un premier fichier persistence.xml
3. Utilisation de ce premier exemple
3.1. Écriture du code d'utilisation
3.2. Exécution de notre premier exemple
3.3. Modification de la class Marin
3.4. Opérations CRUD
Mettre un jeu de classes en base
1. Introduction
2. Définition d'une entité JPA
2.1. Écriture de l'entité
2.2. Annotation de l'entité
2.3. Annotations des champs
2.4. Exemple d'utilisation
3. Opérations sur les entités
3.1. Introduction
3.2. Opération PERSIST
3.3. Opération REMOVE
3.4. Opération REFRESH
3.5. Opération DETACH
3.6. Opération MERGE
4. Mise en relation d'entités
4.1. Introduction
4.2. Relations unidirectionnelles et bidirectionnelles
4.3. Relation 1:1
4.4. Relation 1:p
4.5. Relation p:1
4.6. Relation n:p
4.7. Comportement cascade
4.8. Effacement des entités orphelines
5. Charger des entités et leurs relations
6. Objets inclus
6.1. Introduction
6.2. Déclaration d'un objet inclus
6.3. Utilisation d'objets inclus
6.4. Cas où l'objet inclus est nul
6.5. Renommer les colonnes incluses
6.6. Collections d'objets inclus
L'API Collection en base
1. Introduction
2. Enregistrer une collection d'entités
2.1. Enregistrement d'une collection simple
2.2. Enregistrement d'un Set
2.3. Enregistrement d'une List
3. Enregistrer une collection de types de base
4. Enregistrement d'une Map
4.1. Table de hachage de type (type de base, entité)
4.2. Cas où la clé est un champ de la valeur
4.3. Cas d'une table (entité, entité)
Héritage
1. Introduction
2. Enregistrement d'une hiérarchie de classes
2.1. Entité et super-classe non enregistrée
2.2. Position du problème
2.3. Trois façons de faire
3. Stratégie SINGLE_TABLE
3.1. Fonctionnement
3.2. Mise en place
3.3. Limitations
4. Stratégie JOINED
4.1. Fonctionnement
4.2. Mise en place
4.3. Limitations
5. Stratégie TABLE_PER_CLASS
5.1. Fonctionnement
5.2. Mise en place
5.3. Limitations
Requêtes
1. Introduction
2. Un premier exemple
2.1. Écriture d'une première requête
2.2. Exécution d'une première requête
2.3. Exécution d'une première requête d'agrégation
3. Définition de requêtes
3.1. Requêtes dynamiques
3.2. Requêtes paramétrées
3.3. Requêtes nommées
3.4. Requêtes natives
4. Exécution, analyse du résultat
4.1. Exécution d'une requête dynamique
4.2. Exécution d'une requête nommée
4.3. Analyse du résultat
4.4. Cas des résultats de grande taille
4.5. Remarques
5. Clause From
5.1. Définition des entités
5.2. Jointures dans la clause From
5.3. Remarque finale sur les jointures en JPQL
6. Clause Where
6.1. Variables et chemins dans une clause where
6.2. Expressions conditionnelles et opérateurs
6.3. Requêtes imbriquées
6.4. Opérateurs any, all et some
6.5. Expressions fonctionnelles
7. Clauses Group By et Having
8. Opérations Update et Delete
EJB
1. Introduction
2. Un premier exemple
2.1. Introduction
2.2. Installation dans Glassfish à l'aide de Netbeans
2.3. Création d'un premier EJB
2.4. Déploiement de notre premier EJB
2.5. Création d'un client
3. Mise en oeuvre du pattern session facade
3.1. Introduction
3.2. Modèle objet
3.3. Définition de l'unité de persistance
3.4. Assemblage de notre application
3.5. Assemblage et déploiement
3.6. Utilisation du client
4. Opération de persistance en façade
4.1. Introduction
4.2. Enrichissement du service
4.3. Création de la méthode findMarinById(long)
4.4. Ajout de la méthode findAllMarins()
4.5. Utilisation dans un code client
5. Types d'EJB
5.1. Introduction
5.2. Qu'est-ce qu'un EJB ?
5.3. Écriture d'un EJB session
5.4. Qu'est-ce qu'une méthode métier ?
5.5. EJB avec ou sans état
5.6. Gestion des transactions
5.7. Restrictions
6. Cycle de vie d'un EJB
6.1. Cas des EJB sans état
6.2. Cas des EJB avec état
6.3. Injection de dépendances
7. Transaction gérée par l'EJB
7.1. Introduction
7.2. Déclaration du mode transactionnel
7.3. Gestion de la transaction
7.4. Fonctionnement de la transaction
7.5. Cas des EJB avec état
8. Transaction gérée par le serveur
8.1. Introduction
8.2. Déclaration du mode transactionnel
8.3. Gestion de la transaction
8.4. Fonctionnement de la transaction
8.5. Remarques
9. Intercepteurs
9.1. Introduction
9.2. Aperçu général
9.3. Cycle de vie d'un intercepteur
9.4. Object InvocationContext
9.5. Interception d'un EJB ou d'une méthode métier
9.6. Exemple de mise en œuvre d'un intercepteur