Ressource
Rappel
Dans la section dédiée au transaction JPA nous avons souligné deux cas
- si nous sommes dans un contexte Java SE (l’ensemble des TP précédent) nous devions gérer les transactions et l’injection de dépendances
- si nous utilisons un container EE, alors nous pouvons nous passer de la gestion des transactions et déléguer l’injection au CDI
L’objectif de ce TP est donc de découvrir ces concepts en implémentant une architecture en couche tout en factorisant le code nécessaire.
1. Installer TomEE et lancer le projet
Pour ce projet, nous avons besoin d’un container EE, nous allons utiliser TomEE.
-
Télécharger et importer le projet Maven dans Eclipse
-
Lancer Docker Desktop +
docker compose uppour la base de données -
Lancer en mode debug pour bénéficier du How Swap
-
Rendez-vous sur l’url pour voir si tout fonctionne (attention au port)
http://localhost:9080/jpa-ee-container/helloworld
2. Consignes
Note : pour créer des objets JSON vous pouvez regarder
javax.json: https://docs.oracle.com/javaee/7/api/javax/json/JsonObjectBuilder.html- Utiliser des Map
Partie 1. GenericDAO
- Créer une entité générique BaseEntity qui contiendra l’identifiant commun à toutes les entités.
- Créer une classe générique
GenericDAO<T>pour gérer les opérations CRUD.- Injecter l’entityManager avec
@PersistenceContext(unitName = "myPU") - Coder les méthodes
create(),find(),delete()etfindAll()
- Injecter l’entityManager avec
- Créer une entité Student avec les annotations JPA.
- Créer un DAO spécifique StudentDAO qui hérite du GenericDAO.
- Créer un service
StudentServicesous forme d’un EJB pour gérer les étudiants. - Créer une ressource REST
StudentControllerpour exposer les opérations via une API REST.
Exemple
curl -X GET "http://localhost:8080/jpa-ee-container/students" -H "Accept: application/json"
Partie 1b. Rajouter les Soirées
Les étudiants peuvent participer à des soirées; lorsqu’on récupère un étudiant nous souhaitons lister les soirées où il a participer.
— M’appeler
- comment régler les références circulaires ?
- comment éviter la
LazyInitializationException
Partie 2. Pagination
L’objectif de cette deuxième partie est d’ajouter une fonctionnalité de pagination aux requêtes de récupération des données dans notre GenericDAO.
- Ajouter la méthode
List<T> findAllPaginated(int page, int size) - Ajouter la méthode
long count()
Modifier en conséquence StudentService pour exploiter la pagination et StudentController
// Controller
Response getAllStudents(@QueryParam("page") @DefaultValue("0") int page, @QueryParam("size") @DefaultValue("10") int size) {
}— M’appeler
- à quoi ressemble le retour de l’API ?
Partie 3. Spécification/Criteria API
Nous allons ajouter une méthode findByCriteria(Map<String, Object> criteria) qui permet de rechercher des entités selon des conditions dynamiques.
- Dans
GenericDAOnous allons coder cette fonction. On peut s’appuyer la notion de predicate qui peuvent être chaînés viaandouor(nous on fera duand). Exemple 1
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
Predicate predicate1 = cb.equal(pet.get(Pet_.name), "Fido"); // création d'un prédicat
Predicate predicate2 = cb.equal(pet.get(Pet_.color), "brown"); // création d'un second prédicat
cq.where(predicate1.and(predicate2)); // chaine via and- Puis dans les classes concrètent qui hérite de
GenericDAOnous allons créer nos Prédicats puis appeler cette méthode- Coder
List<Student> searchStudents(String name, Integer age) - qui va créer un prédicat puis appeler la méthode
findByCriteria
- Coder
Complément
Pour ce qui ont fini, vous pouvez rajouter la notion d’héritage
- Étudiant et Professeurs sont des Personnes
- Les Personnes peuvent participer à des soirées