Formation
     Maîtriser JPA/Hibernate pour optimiser les
     performances




©Objet Direct 2011
Version
Présentations

     Votre formateur
     Objet Direct




    Conseil architecture du SI                               Pilotage de l’entreprise
                                      Optimisation et
      Applications métiers       intégration des processus     Optimisation de la
          spécifiques                                            performance




           Web et
           Objet                         ERP                          BI



2
Notre Environnement




3
Présentations

     Quelles sont vos attentes ?
     Quel est votre rôle au sein d’une équipe projet ?




4
Introduction à Hibernate et JPA




5
Présentation des problématiques de
                persistance


     La persistance est le mécanisme qui permet de
      sauvegarder l’état d’une application informatique dans un
      outil de gestion de données
       ● Sur un système de fichier
       ● En base
       ● Sur un bus applicatif
       ● Etc …


     Le mécanisme de persistance est bidirectionnel




6
Du monde des objets vers le monde des
              données


          Gestionnaire                       TBL_GEST

    nom                                    ID
    responsable                            NAME
                                           RESP_ID


                   1



                   n
              anomalie                        TBL_ANO
    numéro                                  ID
    Description                             GEST_ID
                                            NUMBER
                                            DESC

                   1


                   n
              remarque                        remarque
    Contenu                                ID
    auteur                                 ANO_ID
                                           CONTENT
                                           AUTHOR


7
De l’attribut vers les données


     Pour stocker un attribut il faut
       ● Le nom de la table dans laquelle l’attribut va être stocké
       ● Le type de l’attribut
       ● Le nom du champ dans la base de données


     Attention au cas particulier des attributs qui ne sont pas
      des types primitifs. Dans ce cas il faut stocker la relation
       ● Le nom de la table vers laquelle la relation pointe
       ● Définition de la clef étrangère




8
Requêtage fonctionnel


     Le lien avec la base de données étant défini au niveau des
      objets, il n’est plus nécessaire d’utiliser le SQL pour faire
      des requêtes

     On peut utiliser directement les objets du concept pour
      exprimer les données à récupérer
       ● JPQ
       ● HQL
       ● EJB-QL
       ● Etc …


     Les langages de requêtage fonctionnel sont plus proches
      du besoin utilisateur et plus facile à maintenir



9
Hibernate et JPA


      Hibernate
        ● Fournit un DAO générique !
        ● Outil dit de mapping Objet / Relationnel
        ● Depuis plusieurs années, considéré comme une référence
             • Au point que Sun a demandé à l’auteur principal d’Hibernate de superviser la spécification de la
               norme JPA en s’inspirant d’Hibernate
             • JPA (EJB 3) est en rupture complète avec les versions EJB antérieures


      JPA
        ● Java Persistence API
        ● Norme JEE
        ● Hibernate est une implémentation de JPA
        ● Implémentation de référence : EclipseLink
        ● Il existe d’autres implémentations (Websphere, Weblogic, TopLink, …)

      JPA versus Hibernate
        ● JPA est une norme
        ● Hibernate est plus riche en fonctionnalités
             • Et a toujours un temps d’avance sur JPA !



10
Définir un objet persistant


      Un Entity matérialise en Java un objet du domaine de
       l’application
        ● Un objet du domaine est dit « persistant » : son état est conservé en base
          de données
        ● La plupart du temps, un objet du domaine correspond à une ligne d’une table
          de la base de données
      Un Entity est un POJO annoté
      Il est constitué d’une unique classe contenant
        ● Un identifiant unique
            • Il permet d’identifier un objet précisément parmi tous les objets instanciés de cette classe
        ● Des propriétés
            • Elles correspondent aux champs de la BDD
        ● Des méthodes
            • Elles implémentent les règles métiers spécifiques à l’objet du domaine
        ● Un constructeur sans paramètre
            • Les constructeurs avec paramètres sont autorisés, pourvu que le constructeur sans paramètre
              soit présent


11
Rendre une classe persistante
                                Indique qu’il s’agit d’une
                                Entité persistante
                                                             Indique que la propriété « id »
     @Entity                                                 est l’identifiant de l’entité
     class Book {                                            Optionnel : génération
                                                             automatique des valeurs de id
         @Id @GeneratedValue
         private int id;
         public int getId() {return id;}
         public void setId(int id) {this.id = id;}                           Par défaut, title est un
                                                                             attribut persistant
         private String title;
         public String getTitle() {return title;}
         public void setTitle(String title) {this.title = title;}

         @ManyToOne                                                           La propriété « author »
         private Author author;                                               est un lien vers une autre
         public Author getAuthor() {return author;}                           entité
         public void setAuthor(Author author) {this.author = author;}

         private String summary;
         public String getSummary() {return summary;}
         public void setSummary(String summary) {this.summary = summary;}

         @ManyToMany                                                         La propriété « keyWords » est
                                                                             un lien multiple vers une
         private List<KeyWord> keyWords;                                     autre entité
         public List<KeyWord> getKeyWords() {return keyWords;}
         public void setKeyWords(List<KeyWord> keyWords) {this.keyWords = keyWords;}
     }




12
Identité en pratique


      Toute classe Entity doit avoir un et un seul identifiant
        ● Correspond à la clé primaire de la table sur laquelle il est mappé
        ● Cet identifiant est immutable : une fois initialisé, il ne doit pas être
          modifié
        ● Généralement, cet identifiant est une propriété de l’entité
            • Mais on peut constituer un identifiant composé

      La propriété qui définit l’identifiant est annoté avec @Id

                                                                 Identifiant qui doit être intialisé
            @Id                                                  par programmation
            public int id;


                                                           Identifiant initialisé automatiquement par le
            @Id @GeneratedValue                            conteneur en utilisant la stratégie la plus
            public int id;                                 adaptée en fonction de la BDD cible


            @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="bookSeq")
            public int id;
                                                                                      Nom de la séquence
                                                Identifiant initialisé automa-        utilisée
                                                tiquement par le conteneur en
                                                utilisant une séquence


13
Configurer un gestionnaire de persistance


      La configuration est donnée par le fichier
       META-INF/persistence.xml
                  Définition d’un     Classe d’implémentation du
                  gestionnaire        gestionnaire (ici Hibernate)


     <persistence xmlns="http://java.sun.com/xml/ns/persistence"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence            DataSource (BDD)
                                                                                        utilisée
                                   http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
                  version="2.0">
         <persistence-unit name="ticketPU" transaction-type=« JTA">
             <provider>org.hibernate.ejb.HibernatePersistence</provider>
             <jta-data-source>java:/DefaultDS</jta-data-source>
             <properties>
                <property name=“hibernate.show_sql" value="true" />
                <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
                <property name="hibernate.hbm2ddl.auto" value="update" />
             </properties>
         </persistence-unit>
     </persistence>                                          Paramètres spécifiques à
                                                                 l’implémentation du
                                                                 gestionnaire (ici Hibernate)



14
Configuration du DataSource dans Tomcat


      Cf. le fichier server.xml
        ● Répertoire apache-tomcat-7.0.12conf
        ● Dans le plugin eclipse : projet Servers, « Tomcat v7.0 Server at localhost-
          config »
        ● Dans la section GlobalNamingResource ajouter :

          <Resource name="jdbc/ticketPU"
                    type="javax.sql.DataSource"
                    driverClassName="org.h2.Driver"
                    url="jdbc:h2:tcp://localhost//formation/database"
                    password=""
                    username="sa"
                    auth="Container" maxActive="100" maxIdle="30" maxWait="10000" />




        ● Dans la section contexte de la WebApp ajouter :

          <ResourceLink global="jdbc/ticketPU"                                Le nom doit correspondre au nom dans
                     name="jdbc/ticketPU"                                     persistence.xml
                     type="javax.sql.DataSource" />



15
Le gestionnaire de persistance
                                                                          Classe javax.persistence.EntityManager
                                                                          fournie par Java EE

                        Pour accéder aux entités, il faut interroger un
                        gestionnaire de persistance




               Le gestionnaire de persistance sait créer,
               modifier et supprimer des entités ou trouver
               des entités selon leur clé primaire ou une
               requête JPQL (pseudo SQL)



     EntityManager em;
     Client nouveaulient = …
                                                 Le même gestionnaire permet
     em.persist(nouveauClient);                  d’accéder à des entités de types
     Client jbond =                              différents
       em.find(Client.class, "007");
     jbond.setPrenom(«James»);
     Client drNo =
      em.find(Client.class, "666");
     em.remove(drNo);




16
Du POJO à la base …



                                                                                        Transaction
                                                   JTA/JTS              XA
                                                                                           BDD




                JPA           Hibernate                              Connexion          Connexion
                                                  DataSource                                             BDD
           (EntityManager)    (Session)                                JDBC             HSQLDB



                                      Java/JEE

     Pour accéder à
                             Pour transformer        Pour profiter     Pour accéder        Pour        Pour
     l’ORM de façon
                             des objets Java en      des services      à la base à         accéder     stocker les
     standard
                             enregistrements         techniques        partir de Java      à la base   données
                             BDD                     (transactions
                                                     distribuées,
                                                     pooling



17
Le gestionnaire de persistance



                                    On peut déclarer plusieurs
                                    gestionnaires de persistance




     Une gestionnaire de
     persistance ne peut être
     utilisé que par un seul
     thread à la fois




                         Utile pour accéder à plusieurs
                         bases de données (mode XA
                         possible)



18

Objet Direct Formation JPA Hibernate

  • 1.
    Formation Maîtriser JPA/Hibernate pour optimiser les performances ©Objet Direct 2011 Version
  • 2.
    Présentations  Votre formateur  Objet Direct Conseil architecture du SI Pilotage de l’entreprise Optimisation et Applications métiers intégration des processus Optimisation de la spécifiques performance Web et Objet ERP BI 2
  • 3.
  • 4.
    Présentations  Quelles sont vos attentes ?  Quel est votre rôle au sein d’une équipe projet ? 4
  • 5.
  • 6.
    Présentation des problématiquesde persistance  La persistance est le mécanisme qui permet de sauvegarder l’état d’une application informatique dans un outil de gestion de données ● Sur un système de fichier ● En base ● Sur un bus applicatif ● Etc …  Le mécanisme de persistance est bidirectionnel 6
  • 7.
    Du monde desobjets vers le monde des données Gestionnaire TBL_GEST nom ID responsable NAME RESP_ID 1 n anomalie TBL_ANO numéro ID Description GEST_ID NUMBER DESC 1 n remarque remarque Contenu ID auteur ANO_ID CONTENT AUTHOR 7
  • 8.
    De l’attribut versles données  Pour stocker un attribut il faut ● Le nom de la table dans laquelle l’attribut va être stocké ● Le type de l’attribut ● Le nom du champ dans la base de données  Attention au cas particulier des attributs qui ne sont pas des types primitifs. Dans ce cas il faut stocker la relation ● Le nom de la table vers laquelle la relation pointe ● Définition de la clef étrangère 8
  • 9.
    Requêtage fonctionnel  Le lien avec la base de données étant défini au niveau des objets, il n’est plus nécessaire d’utiliser le SQL pour faire des requêtes  On peut utiliser directement les objets du concept pour exprimer les données à récupérer ● JPQ ● HQL ● EJB-QL ● Etc …  Les langages de requêtage fonctionnel sont plus proches du besoin utilisateur et plus facile à maintenir 9
  • 10.
    Hibernate et JPA  Hibernate ● Fournit un DAO générique ! ● Outil dit de mapping Objet / Relationnel ● Depuis plusieurs années, considéré comme une référence • Au point que Sun a demandé à l’auteur principal d’Hibernate de superviser la spécification de la norme JPA en s’inspirant d’Hibernate • JPA (EJB 3) est en rupture complète avec les versions EJB antérieures  JPA ● Java Persistence API ● Norme JEE ● Hibernate est une implémentation de JPA ● Implémentation de référence : EclipseLink ● Il existe d’autres implémentations (Websphere, Weblogic, TopLink, …)  JPA versus Hibernate ● JPA est une norme ● Hibernate est plus riche en fonctionnalités • Et a toujours un temps d’avance sur JPA ! 10
  • 11.
    Définir un objetpersistant  Un Entity matérialise en Java un objet du domaine de l’application ● Un objet du domaine est dit « persistant » : son état est conservé en base de données ● La plupart du temps, un objet du domaine correspond à une ligne d’une table de la base de données  Un Entity est un POJO annoté  Il est constitué d’une unique classe contenant ● Un identifiant unique • Il permet d’identifier un objet précisément parmi tous les objets instanciés de cette classe ● Des propriétés • Elles correspondent aux champs de la BDD ● Des méthodes • Elles implémentent les règles métiers spécifiques à l’objet du domaine ● Un constructeur sans paramètre • Les constructeurs avec paramètres sont autorisés, pourvu que le constructeur sans paramètre soit présent 11
  • 12.
    Rendre une classepersistante Indique qu’il s’agit d’une Entité persistante Indique que la propriété « id » @Entity est l’identifiant de l’entité class Book { Optionnel : génération automatique des valeurs de id @Id @GeneratedValue private int id; public int getId() {return id;} public void setId(int id) {this.id = id;} Par défaut, title est un attribut persistant private String title; public String getTitle() {return title;} public void setTitle(String title) {this.title = title;} @ManyToOne La propriété « author » private Author author; est un lien vers une autre public Author getAuthor() {return author;} entité public void setAuthor(Author author) {this.author = author;} private String summary; public String getSummary() {return summary;} public void setSummary(String summary) {this.summary = summary;} @ManyToMany La propriété « keyWords » est un lien multiple vers une private List<KeyWord> keyWords; autre entité public List<KeyWord> getKeyWords() {return keyWords;} public void setKeyWords(List<KeyWord> keyWords) {this.keyWords = keyWords;} } 12
  • 13.
    Identité en pratique  Toute classe Entity doit avoir un et un seul identifiant ● Correspond à la clé primaire de la table sur laquelle il est mappé ● Cet identifiant est immutable : une fois initialisé, il ne doit pas être modifié ● Généralement, cet identifiant est une propriété de l’entité • Mais on peut constituer un identifiant composé  La propriété qui définit l’identifiant est annoté avec @Id Identifiant qui doit être intialisé @Id par programmation public int id; Identifiant initialisé automatiquement par le @Id @GeneratedValue conteneur en utilisant la stratégie la plus public int id; adaptée en fonction de la BDD cible @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="bookSeq") public int id; Nom de la séquence Identifiant initialisé automa- utilisée tiquement par le conteneur en utilisant une séquence 13
  • 14.
    Configurer un gestionnairede persistance  La configuration est donnée par le fichier META-INF/persistence.xml Définition d’un Classe d’implémentation du gestionnaire gestionnaire (ici Hibernate) <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence DataSource (BDD) utilisée http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="ticketPU" transaction-type=« JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/DefaultDS</jta-data-source> <properties> <property name=“hibernate.show_sql" value="true" /> <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" /> <property name="hibernate.hbm2ddl.auto" value="update" /> </properties> </persistence-unit> </persistence> Paramètres spécifiques à l’implémentation du gestionnaire (ici Hibernate) 14
  • 15.
    Configuration du DataSourcedans Tomcat  Cf. le fichier server.xml ● Répertoire apache-tomcat-7.0.12conf ● Dans le plugin eclipse : projet Servers, « Tomcat v7.0 Server at localhost- config » ● Dans la section GlobalNamingResource ajouter : <Resource name="jdbc/ticketPU" type="javax.sql.DataSource" driverClassName="org.h2.Driver" url="jdbc:h2:tcp://localhost//formation/database" password="" username="sa" auth="Container" maxActive="100" maxIdle="30" maxWait="10000" /> ● Dans la section contexte de la WebApp ajouter : <ResourceLink global="jdbc/ticketPU" Le nom doit correspondre au nom dans name="jdbc/ticketPU" persistence.xml type="javax.sql.DataSource" /> 15
  • 16.
    Le gestionnaire depersistance Classe javax.persistence.EntityManager fournie par Java EE Pour accéder aux entités, il faut interroger un gestionnaire de persistance Le gestionnaire de persistance sait créer, modifier et supprimer des entités ou trouver des entités selon leur clé primaire ou une requête JPQL (pseudo SQL) EntityManager em; Client nouveaulient = … Le même gestionnaire permet em.persist(nouveauClient); d’accéder à des entités de types Client jbond = différents em.find(Client.class, "007"); jbond.setPrenom(«James»); Client drNo = em.find(Client.class, "666"); em.remove(drNo); 16
  • 17.
    Du POJO àla base … Transaction JTA/JTS XA BDD JPA Hibernate Connexion Connexion DataSource BDD (EntityManager) (Session) JDBC HSQLDB Java/JEE Pour accéder à Pour transformer Pour profiter Pour accéder Pour Pour l’ORM de façon des objets Java en des services à la base à accéder stocker les standard enregistrements techniques partir de Java à la base données BDD (transactions distribuées, pooling 17
  • 18.
    Le gestionnaire depersistance On peut déclarer plusieurs gestionnaires de persistance Une gestionnaire de persistance ne peut être utilisé que par un seul thread à la fois Utile pour accéder à plusieurs bases de données (mode XA possible) 18