Exercice 3 - Utilisation de JPA⚓︎
Nous allons modifier le projet Web Dynamique, appelé GestionNotes, afin d'utiliser l'API JPA.
1. Utilisation du runtime WildFly⚓︎
Tout d'abord, il faut modifier la runtime du projet. Comme indiqué plus tôt, Tomcat est très léger, et ne permet pas d'utiliser l'API JPA.
Pour cela, il suffit de faire un clic droit sur le projet, puis :material-mouse:Properties
, puis :material-file-tree:Project Facets
. Dans l'onglet Runtimes
, déselectionner Tomcat
et sélectionner la runtime WildFly
à la place :
2. Activation de JPA⚓︎
Pour pouvoir utiliser JPA, il faut l'indiquer dans les "facettes" du projet.
Pour cela, au même endroit (il faut faire un clic droit sur le projet GestionNotes, cliquer sur :material-mouse:Properties
et aller dans :material-file-tree:Project Facets
), cocher la case JPA et enfin cliquer sur
Dans la vue Explorer, le fichier 📄persistence.xml
apparaît. Il va nous permettre de gérer la persistance des beans Java :
3. Configuration de JPA⚓︎
Le fichier 📄persistence.xml
permet de configurer toutes la partie persistance.
Ouvrir ce fichier. Dans Eclipse, il y a plusieurs onglets. Le dernier, Source
, permet de modifier le fichier XML directement. Tous les autres sont une "interface graphique" qui permet d'effectuer ces modifications plus simplement. Ici, nous allons utiliser cette "interface graphique". Il est indiqué ci-dessous, dans le bloc "Si besoin, modification manuelle du fichier 📄persistence.xml", comment faire ces mêmes modifications directement dans le XML.
- Dans l'onglet
Connection
:- Dans
Transaction Type
, indiquerJTA
. - Dans
JTA data source
, précier le nom de la source créées précédemment. Normalement, il s'agit dejava:/MySqlGestionNotesJPA
.
- Dans
- Dans l'onglet
Schema Generation
:-
Dans
Database action
, sélectionnerDrop and Create
.:warning::warning: Attention, cela signifie qu'à chaque redémarrage de l'application, toutes les tables du schéma sont supprimées et recréées. C'est très pratique en mode développement, puisque des champs peuvent être ajoutés et/ou supprimés régulièrement, mais une fois que les développements sont terminés, il faut bien sûr repasser cette valeur à
None
. :warning::warning:
-
Si besoin, modification manuelle du fichier 📄persistence.xml
Dans ce fichier 📄persistence.xml
:
- Le nom de l'unité de persistance (attribut
name
de la balisepersistence-unit
) est très important, il faut l'indiquer dans les classes DAO pour indiquer sur quelle base de données les requêtes doivent être effectuées.
Par défaut, il n'y a qu'une seule unité de persistance, dont le nom est le nom du projet Java (GestionNotes ici). - Nous allons indiquer que nous utilisons l'API JTA pour gérer les transactions. Pour cela, il faut ajouter l'attribut
transaction-type="JTA"
dans la balise<persistence-unit>
. - À l'intérieur de cette balise
<persistence-unit>
, nous allons ajouter la balise fille<jta-data-source>java:/MySqlGestionNotesJPA</jta-data-source>
pour faire le lien avec la datasource créée précédemment (on indique le nom JNDI). -
Enfin, on indique la stratégie utilisée au redémarrage du serveur. Ici, nous sommes en mode "développement", nous allons donc supprimer et re-créer la table correspondante à chaque redémarrage. Pour cela, à l'intérieur de
<persistence-unit>
, ajouter une balise<properties>
. Cette balise va elle même contenir la balise fille suivante :📄 persistence.xml 1 2 3
<properties> <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/> </properties>
4. Gestion du modèle - Persistance du bean⚓︎
Le bean étant déjà créé, il va falloir faire des modifications "à la main" pour gérer la persistance. Lorsqu'on en créé un nouveau, ce que vous ferez par exemple dans le TP noté, c'est plus facile (Cf. bloc "Pour la prochaine fois, création d'un nouveau bean JPA" ci-dessous).
-
Nous allons commencer par indiquer que le bean
fr.univtours.polytech.gestionnotes.model.NoteBean
doit être "persisté". Pour cela, il suffit de faire un clic droit sur la classe, puis :material-mouse:JPA Tools > Add to Persistence Unit
.Effet dans 📄persistence.xml
Dans le fichier 📄
persistence.xml
, la ligne ci-dessous a été automatiquement ajoutée :📄 persistence.xml 1
<class>fr.univtours.polytech.gestionnotes.model.NoteBean</class>
-
Une erreur apparaît alors, qui indique que le bean est référencé, mais pas annoté. Il faut donc annoter ce bean. Pour cela, on ajoute l'annotation
@Entity
:☕ Code Java - Entité NoteBean 1 2
@Entity//(1)! public class NoteBean implements Serializable {//(2)!
- Indique qu'il s'agit d'un bean JPA.
- Et oui, c'est un bean, il ne faut donc pas oublier que la classe doit implémenter
java.io.Serializable
!
Comme la nouvelle erreur l'indique, il faut préciser quelle est la clef primaire. Sur la propriété
id
, on indique donc cela. On en profite également pour préciser que la valeur est auto incrémentée (ce qui n'est pas une obligation) :☕ Code Java - Entité NoteBean 1 2 3
@Id //(1)! @GeneratedValue(strategy = GenerationType.IDENTITY) //(2)! private Integer id;
- Indique qu'il s'agit de la clef primaire.
- Cela correspond exactement au
auto_increment
que nous avions mis sur le champid
de la tableNOTE
dans l'exercice 1 de ce TD.
Changement du nom de la table
Par défaut, le nom du bean doit être le même que le nom de la table en base. De même, les noms des propriétés de la classe doivent être les mêmes que les noms de champs de la table.
Si ce n'est pas le cas, il est bien sûr possible de le préciser dans les annotations. Ici par exemple, la table s'appelle
NOTE
, alors que le bean s'appelleNoteBean
. Pour que le lien (le mapping) puisse se faire correctement, il faut le préciser dans l'annotation :☕ Code Java - Entité NoteBean 1 2 3
@Entity @Table(name = "NOTE")//(1)! public class NoteBean implements Serializable {
- Il n'y a que cette ligne à rajouter ici.
Ce site liste les différentes options possibles.
Pour la prochaine fois, création d'un nouveau bean JPA
Il est possible de créer directement un bean, en précisant qu'il est persisté avec JPA.
Pour cela, il suffit de faire un clic droit sur le projet, puis :material-mouse:New > JPA Entity
. Indiquer fr.univtours.polytech.gestionnotes.model
comme package, et NoteBean
comme classe, puis cliquer sur
id
comme key), puis clique sur id
. On souhaite qu'il soit automatiquement incrémenté (d'un en un). On ajoute donc, juste en dessous de l'annotation @id
, l'annotation @GeneratedValue(strategy = GenerationType.IDENTITY)
. On a donc :
☕ Code Java - Entité NoteBean | |
---|---|
1 2 3 |
|
- Cela correspond exactement au
auto_increment
que nous avions mis sur le champid
de la tableNOTE
dans l'exercice 1 de ce TD.
Le fichier 📄persistence.xml
Le fichier doit maintenant ressembler à cela :
📄 persistence.xml | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
- Dans les
DAOs
, on aura besoin du nom de l'unité de persistance pour savoir sur quelle base de données envoyer les requêtes.
Plus d'infos surtransaction-type
ici. - Ici, il faut indiquer le même nom JNDI que celui précisé à la création de la Data Source précédemment.
- Liste tous les beans qui sont persistés avec JPA.
- Cela signifie qu'à chaque démarrage du serveur, les tables correspondantes sont supprimées et recréées. On évitera bien sûr de laisser cette option en environnement de production ...
Vérification en base de données
Il est maintenant temps de tester. Pour cela, on démarre le serveur (si ce n'est pas déjà fait), puis on publie le projet (GestionNotes) sur le serveur. Pour cela, on fait un clic droit sur le serveur, :material-mouse:Add and Remove...
, et on déploie GestionNotes.
On vérifie que la table Note
est bien créée en BDD (et vide), avec les quatre champs indiqués.
3. Création de la couche DAO⚓︎
Nous allons créer une nouvelle implémentation de cette couche (c'est-à-dire une nouvelle classe implémentant l'interface NotesDAO
) :
- On crée un objet
EntityManager
, avec le nom de l'unité de persistance en paramètre (celle indiquée dans l'attributname
de la balisepersistence-unit
dans le 📄persistence.xml
). - Cet objet gère pour nous les requêtes en BDD, avec le langage HQL (pour Hibernate Query Language) - appelé également JPAQL (pour Java Persistence API Query Language) - et l'utilisation des méthodes
find
,persist
,createQuery
, ...
Voici maintenant à quoi ressemble la classe NotesDAOImplJPA
:
☕ Code Java - Classe NotesDAOImplJPA | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
4. Modification de la couche métier⚓︎
Il n'y a qu'une seule modification à effectuer : modifier l'implémentation du DAO utilisée. Pour cela, dans le constructeur de la classe NotesBusinessImpl
, remplacer la ligne existante par :
☕ Code Java - Classe NotesBusinessImpl - Contructeur | |
---|---|
1 2 3 |
|
5. Récupération de la couche présentation⚓︎
Il n'y a aucune modification à apporter sur cette couche pour le moment.
Vérification
Vérifier maintenant que cette nouvelle version de l'application est bien fonctionnelle.
Contrairement à Tomcat où il fallait redémarrer le serveur à chaque modification, avec WildFly, il suffit de déployer l'application, en faisant un clic droit, puis :material-mouse:Full Publish
.
Il est bien sûr possible de faire à chaque fois un redémarrage du serveur, mais cette méthode est plus rapide, surtout lorsqu'il y a plusieurs applications déployées sur le serveur.