Comme mentionné en début du sujet, un ORM doit être capable de se connecter à la base de données qui va stocker
les informations manipulées par l’application. Pour ce faire, il faut que le programmeur fournisse, dans un fichier de configuration,
les informations nécessaires à cette connexion. Dans le cas de JPA, c’est le fichier persistence.xml dans src/main/ressources/META-INF
qui doit contenir cette information. On doit y retrouver notamment l’adresse où se trouve la base de données, et le login et mot de passe que
l’application doit utiliser pour se connecter.
Le fichier de configuration
Pour votre application, en analysant le contenu du fichier persistence.xml, trouvez les informations suivantes :
le nom de la base de données PostgreSQL qui sera utilisée – comrec_db
le login utilisé pour accéder à la base – pguser
le mot de passe correspondant à ce login – pgpwd
le mode d’interaction entre l’application et la base de données (propriété ddl-generation) – drop-and-create-tables
le nom des classes Java dont les instances seront « persistées » (on dit qu’elles seront mappées dans la base de données) – Dept.java
le fournisseur JPA à utiliser – org.eclipse.persistence.jpa.PersistenceProvider
Question 1
Quelles sont les tables de la base ? Quelles sont leur colonnes ? Quelles données elles contiennent ?
On a une table departments qui a trois colonnes (dept_no, dname, dept_loc) et 3 lignes avec 1, 2 et 3 comme dept_no.
Question 2
Lancez l’exécution de l’application. Analysez à nouveau les tables de la base de données ? Y a t’il eu des changements ? Lesquels ?
On a une table departments avec trois colonnes (dept_no, dname, dept_loc) et 3 lignes avec 1, 2 et 3 comme dept_no. Donc, pas de changements.
– OPTIONNAL – Question 3
Changez la valeur de la propriété ddl-generation pourqu’elle soit none. A l’aide de Docker Desktop supprimez le service db et relancez le (docker compose up -d). Analysez les tables de la base de données (nom des colonnes et contenu de la table). Lancez l’application et regardez à nouveau la base. Y a t’il eu des changements ? Lesquels ?
3 nouvelles lignes se sont ajouté aux 3 existantes dans la table departments : on a alors 6 lignes. Et les colonnes sont toujours les mêmes.
Mapping d’une classe
Mapping classe - table
Mapping attribut - colonne
Question 4
D’après les annotations dans la classe Dept.java fournie, répondez aux questions suivantes :
quel est le nom de table qui contiendra les instances de la classe ? – departments
quel est le nom de la colonne correspondant à l’attribut dName ? – dname
modifiez le nom de la colonne correspondant à l’attribut dName, elle doit s’appeler dept_name – @Column(name="dept_name")
Contraintes de clé primaire
D’autres éléments d’une entité
Exercice 1
Mapping des associations entre classes
Question 5
Modifiez les classes Dept.java et Emp.java pour implémenter l’association work at telle que décrite précédemment
(pensez à ajouter les accesseurs des nouveaux attributs et à modifier la méthode toString qui donne une description de l’instance).
Exécutez l’application et vérifiez que les changements dans les tables de la base de données ont bien eu lieu.
Exercice 2
Modifiez la classe Emp.java pour implémenter l’association manager-lowers. Le nom de la clé étrangère doit être mngr_fk
(à nouveau, pensez à modifier la méthode toString). Vérifiez que les changements dans la table employees ont bien eu
lieu. Quels sont ces changements ?
L’Entity Manager
Le contexte transactionnel
Question 6
Complétez le code de la méthode createEmployees(EntityManager) de la classe Main.java. Elle doit permettre de créer trois employés (king, jones et smith)
dans la base de données et doit afficher à la fin les employés existant dans la base de données.
privatevoidcreateEmployees(EntityManager em) {
System.out.println("\n-- Start simple employees creation --");
Emp king, jones, smith;
System.out.println("==== Create employees in memory ====");
try {
king =new Emp("KING", "PRESIDENT", null, null,
new SimpleDateFormat("dd-mm-yy").parse("17-11-81"), 5000, 0);
jones =new Emp("JONES", "MANAGER", null, null,
new SimpleDateFormat("dd-mm-yy").parse("04-12-81"), 2975, 0);
smith =new Emp("SMITH", "CLERK", null, null,
new SimpleDateFormat("dd-mm-yy").parse("17-12-80"), 800, 0);
} catch (ParseException e) {
System.err.println("ERROR CREATING EMPLOYEES (DATE PARSING PB)");
return;
}
System.out.println("===== Persist employees data ====\n ");
em.getTransaction().begin();
try {
em.persist(king);
em.persist(jones);
em.persist(smith);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
e.printStackTrace();
} finally { // Either if new employees are created or not, display the employees existing in// the database System.out.println("===== Display employees data =====");
Query q = em.createNativeQuery("select e from employees e");
List<Emp> empList = (List<Emp>) q.getResultList();
System.out.println(empList);
}
}
Les méthodes de l’Entity Manager
La méthode persist
La méthode find
Question 7
Ajoutez la méthode private void createDepartmentsWithEmployees(EntityManager em) à la classe Main.
privatevoidcreateDepartmentWithEmployees(EntityManager em) {
System.out.println("\n-- Start departments with employees creation --");
System.out.println("==== Create departments in memory ====");
Dept research =new Dept("RESEARCH", "Brest");
Dept accounting =new Dept("ACCOUNTING", "Rennes");
System.out.println("==== Create employees in memory ====");
Emp king, jones, blake, scott, ford;
try {
king =new Emp("KING", "PRESIDENT", null, null,
new SimpleDateFormat("dd-mm-yy").parse("17-11-81"), 5000, 0);
jones =new Emp("JONES", "MANAGER", null, null,
new SimpleDateFormat("dd-mm-yy").parse("04-12-81"), 2975, 0);
blake =new Emp("BLAKE", "ANALYST", null, null,
new SimpleDateFormat("dd-mm-yy").parse("01-05-81"), 2850, 0);
scott =new Emp("SCOTT", "ANALYST", null, null,
new SimpleDateFormat("dd-mm-yy").parse("09-12-82"), 3000, 0);
ford =new Emp("FORD", "ANALYST", null, null,
new SimpleDateFormat("dd-mm-yy").parse("03-12-81"), 3000, 0);
} catch (ParseException e) {
System.err.println("ERROR CREATING EMPLOYEES (DATE PARSING PB)");
return;
}
System.out.println("===== Affect employees to department ====\n ");
king.setDept(research);
jones.setDept(research);
blake.setDept(accounting);
scott.setDept(accounting);
ford.setDept(accounting);
System.out.println("===== Add employees to department ====\n ");
research.affectEmp(king);
research.affectEmp(jones);
accounting.affectEmp(blake);
accounting.affectEmp(scott);
accounting.affectEmp(ford);
System.out.println("===== Affect a manager to employees ====\n ");
jones.setManager(king);
blake.setManager(king);
scott.setManager(jones);
ford.setManager(jones);
System.out.println("===== Affect collaborators to an employee ====\n ");
king.addLower(jones);
king.addLower(blake);
jones.addLower(scott);
jones.addLower(ford);
System.out.println("===== Persist departments and employees data ====\n ");
em.getTransaction().begin();
try {
em.persist(research);
em.persist(accounting);
em.persist(king);
em.persist(jones);
em.persist(blake);
em.persist(scott);
em.persist(ford);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
e.printStackTrace();
} finally { // Either if new department is created or not, display the department System.out.println("===== Display departments data =====");
System.out.println(em.createNativeQuery("select d from departments d").getResultList());
System.out.println("===== Display employees data =====");
System.out.println(em.createNativeQuery("select e from employees e").getResultList());
}
}
Question 8
Modifiez l’application pour qu’elle permette de trouver les collaborateurs d’un employé donné.