3. Utilisation de ce premier exemple

3.1. Écriture du code d'utilisation

La classe Marin écrite est une classe Java standard, elle ne comporte aucune autre particularité que ses annotations, et nous pouvons donc l'utiliser comme toute classe standard. Écrivons un premier code capable de créer un marin en base.

Exemple 3. Un premier code utilisant une classe persistante

public  class TestJPA {

     public  static  void main(String... args) {

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-test") ;

        EntityManager em = emf.createEntityManager() ;

        Marin marin =  new Marin() ;
        em.getTransaction().begin() ;
        em.persist(marin) ;
        em.getTransaction().commit() ;

        System.out.println("Id = " + marin.getId()) ;
    }
}

Analysons ce code. Tout d'abord, on constate qu'il s'agit d'une classe Java normale, comportant une méthode main standard, que nous allons pouvoir exécuter. Le point d'entrée d'un code permettant de manipuler des entités JPA est un objet de type EntityManagerFactory. Il se crée de façon standard par la ligne de code indiquée. Le nom jpa-test doit correspondre à une unité de persistance définie dans un fichier persistence.xml. Si cette unité de persistance n'existe pas, ou que ce fichier ne se trouve pas à sa place (répertoire META-INF), alors ce code ne pourra pas fonctionner. Cet objet de type EntityManagerFactory modélise notre unité de persistance. C'est à partir de lui que l'on peut construire des objets de type EntityManager, qui nous permettent d'interagir avec la base. Le code de l'exemple construit ensuite un objet de type Marin, et le passe en paramètre de la méthode persist() de notre objet de type EntityManager. Cet appel a pour effet d'écrire en base l'objet marin passé en paramètre. Remarquons que, comme pour toute opération de modification de données en base, cette écriture doit être exécutée dans une transaction. C'est l'objet de l'appel em.begin(), puis em.commit() pour valider l'écriture des données en base.

3.2. Exécution de notre premier exemple

Si l'on exécute ce code normalement, et que tout est correctement configuré, alors on doit voir apparaître dans la console NetBeans le message Id = 1, qui indique que le marin a été correctement écrit en base. Examinons l'état de la base de données.
État de la base de données après une première exécution

Figure 7. État de la base de données après une première exécution


On se rend compte qu'EclipseLink a créé deux éléments : une table Marin, dans laquelle se trouve notre premier marin, et une table Sequence. Cette seconde table est une table technique qu'EclipseLink utilise pour générer ses clés primaires.

3.3. Modification de la class Marin

La classe Marin générée par NetBeans ne va pas nous être d'une grande utilité, au-delà de nous montrer que notre configuration fonctionne. La seule information qu'elle porte est sa clé primaire, ce qui est un peu maigre. Ajoutons trois propriétés à notre classe Marin : nom, prenom et age, et ajoutons également les getters et setters associés. Puis modifions notre code de façon à donner des valeurs à ces propriétés. En exécutant le code de test déjà écrit, on se rend compte qu'EclipseLink a automatiquement pris en compte les nouvelles propriétés de notre classe Marin, et écrit les valeurs de ces propriétés en base.
État de la base de données après modification de la classe Marin

Figure 8. État de la base de données après modification de la classe Marin


3.4. Opérations CRUD

Toutes les opérations de modification de la base doivent se faire dans une transaction, donc entre l'appel à em.begin() et em.commit(). Il existe également une méthode em.rollback(), qui permet d'annuler une transaction.

3.4.1. Création

La création d'un nouvel objet en base se fait par appel à la méthode entityManager.persist(). L'objet sera créé en base sur appel à la méthode commit() de la transaction. Toutefois, la valeur de la clé primaire est fixée sur appel à entityManager.persist().

3.4.2. Mise à jour

Il n'y a pas de méthode à appeler pour mettre à jour une valeur en base. Dès qu'un objet est persistant, et que l'on modifie un de ses champs dans le cadre d'une transaction, alors sa valeur en base sera modifiée en fonction.

3.4.3. Effacement

Pour effacer un objet de la base, il suffit d'appeler la méthode entityManager.remove() en passant cet objet en paramètre. Cet appel génère une opération delete en base de données.

3.4.4. Recherche à partir d'une clé primaire

L'objet entityManager expose une méthode find qui s'utilise de la façon suivante.

Exemple 4. Utilisation de la méthode entityManager.find(...)

Marin marin = entityManager.find(Marin.class,  1L) ;

Cette méthode prend deux éléments en paramètre :
  • Une classe persistante, l'objet recherché sera une instance de cette classe.
  • Une clé primaire.
L'objet retourné est nécessairement une instance de la classe passée en paramètre.
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