PARTIE 2 Mise en place de la persistance JAVA EE JPA & définition du métier Présentation Durant cette partie, nous allons explorer le standard JAVA EE « JPA » qui définit une harmonisation du mode de création d’objets métiers, de gestion des transactions, d’accès aux ressources de persistance. Le mode de persistance ainsi mis en place, nous l’utiliserons pour définir des services REST déclenchant des opérations persistantes. Adresses utiles : - - JPA : o JSR-220 : https://jcp.org/en/jsr/detail?id=220 o JSR-317 : https://jcp.org/en/jsr/detail?id=317 Hibernate : http://hibernate.org/ Junit : http://junit.org/ Étapes de mise en place Définition de JPA - Intégrer un nouveau fichier « persistence.xml » dans le classpath, à la racine, dans un répertoire « META-INF » o « META-INF » est un répertoire normé, présent dans les JAR, WAR, … qui permet de spécifier des propriétés globales, par properties, XML, … o Utiliser le fichier fourni. L’arborescence doit avoir cette structure : GMIN30F/MORASSUT Page 15 Définition des objets métiers La mise en place des objets métiers va se faire en deux étapes : - Définir la super classe des objets métiers, leur contrat commun Définir les objets concrètement et décider de leurs modalités de mapping sur la base de données relationnelle. Superclasse des objets métiers La mise en place d’une « super classe » des objets métiers va nous permettre de mettre en commun des mécanismes et des comportements. Dans le cas de ce TP, nous voulons mettre en commun la gestion du champ identifiant afin qu’il soit traité de manière uniforme dans tous les objets métiers. Créer un package « common », il regroupera les définitions de classes-mère Intégrer une interface « IPersistentObject » étendant « java.io.Serializable ». Cette interface reste vide. Intégrer une implémentation « PersistentObjectImpl » de l’interface définie au point précédent. Intégrer l’annotation de classe « @MappedSuperClass » Intégrer le champ suivant : @Id @GeneratedValue @Column(name = "id", unique = true, nullable = false) private Integer id; Créer les accesseurs de ce champ (get/set) Objets métiers Créer un package « model », il regroupera toutes les définitions d’objet métier Définir les classes « MBookmark », « MTag », « MUser » (préfixe « M » pour simplifier les recherches de classes via Eclipse, utile dans les grands projets) A respecter : o Utiliser les annotations JPA : @Entity, @Table, @Column, @ManyToOne, @ManyToMany o Vous pouvez utiliser des annotations de validation (ex : @NotNull, etc.) o Intégrer explicitement un constructeur sans arguments o Intégrer un « toString » affichant ID/Version Fourniture d’une classe exemple Si vous republiez le projet au niveau du serveur d’applications, cela vous permettra de valider que vos déclarations sont statiquement correctes. GMIN30F/MORASSUT Page 16 Définition des services Dans cette partie, nous allons créer un premier service que nous injecterons dans notre service REST « helloworld » Création du service - Créer un package « service », avec un sous package « impl » Créer une interface « IServiceHelloworld » dans le package « service ». Vide. Définir une opération « String getHtml() » dans cette interface Créer une classe implémentant l’interface précédemment définie, placée dans le package « impl » et nommée « ServiceHelloworld » Implémenter la méthode créée avec un contenu arbitraire Injection du service dans le service REST - Déclarer un attribut d’injection du service créé précédemment dans la classe Helloworld gérant le service REST : @InjectParam private IServiceBookmark serviceBookmark; - Utiliser cet attribut dans votre implémentation de service REST, remplacer l’implémentation précédente par un appel à la méthode définie dans ce service Tester. Remarque : si vous rencontrez des problèmes de déploiement, effectuez la partie « Ajout de SLF4J » pour disposer de traces étendues. Ces traces permettent d’avoir toutes les informations sur les soucis éventuels de déploiement. Premier services : enregistrement et listing Intégrer à votre service les méthodes suivantes : public MBookmark save(final MBookmark newInstance) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("tp"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); em.persist(newInstance); em.flush(); em.getTransaction().commit(); em.close(); emf.close(); return newInstance; } GMIN30F/MORASSUT Page 17 public List<MBookmark> getAll() { EntityManagerFactory emf = Persistence.createEntityManagerFactory("tp"); EntityManager em = emf.createEntityManager(); List<MBookmark> list = em.createQuery("from MBookmark").getResultList(); em.close(); emf.close(); } On peut remarquer notamment : - - La gestion de transactions (em.getTransaction). Dans notre cas, elle est très simple. La création d’un entityManagerFactory : voir que le nom défini dans notre « persistence.xml » pour le « persistence unit » est ici réutilisé pour faire référence à la configuration que nous désirons utiliser. La création d’un entityManager La création d’une requête. Dans le cas de la requête exposée, on peut remarquer : o L’utilisation du nom objet « MBookmark » o L’absence de clause « SELECT » car JPQL supporte la translation relationnel vers objet automatiquement Ces deux exemples de méthodes vont vous permettre d’exposer deux services REST : - Ajout d’enregistrement dans la table bookmark Récupération de toutes les lignes de la table bookmark Ainsi, vous pouvez utiliser ces deux services pour vérifier que votre persistance fonctionne bien : - Un service pour ajouter une entité Un service retournant la liste des entités ou le nombre des entités présentes Ajout de SLF4J Log4j/SLF4J vont nous permettre d’avoir un canal de log reconnu par le serveur d’application. Ainsi, les messages seront configurables globalement. Ajouter le fragment suivant au pom : pom.xml <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.4</version> <scope>runtime</scope> </dependency> Ajouter le fichier « log4j.properties » dans le répertoire « classes » GMIN30F/MORASSUT Page 18 Nb. Le répertoire « classes » est le répertoire père du « META-INF » où nous avions mis le fichier « persistence.xml » ### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L \u2013 %m%n log4j.rootLogger=debug, stdout Dans les traces du serveur, nous pourrons désormais voir les informations de debug de JPA et des autres composants. Vous observerez notamment la création automatique de schéma. Finalisation des travaux Nous avons à présent un serveur REST fonctionnel sur une source de données relationnelles à travers une pile JPA. Nos entités métier sont définies en indépendance de la source de données et les classes de service permettent de découpler le code de gestion du code de prise en charge des informations métier. Pour la suite, vous devez définir : - Les services REST additionnels : BookmarkResouce, TagResource. Ils vous serviront à définir les services REST à implémenter (cf. liste proposée au début du document) Les services réalisant les opérations de persistance GMIN30F/MORASSUT Page 19
© Copyright 2024 ExpyDoc