Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. JPA et Java Hibernate
  3. Pour aller plus loin
Extrait - JPA et Java Hibernate Apprenez le mapping objet-relationnel (ORM) avec Java
Extraits du livre
JPA et Java Hibernate Apprenez le mapping objet-relationnel (ORM) avec Java Revenir à la page d'achat du livre

Pour aller plus loin

Maven

Maven est un outil maintenu par la fondation Apache qui permet de gérer et d’automatiser la production de logiciels développés en Java. Pour simplifier, il permet grâce à un fichier de configuration (le fichier POM) de gérer les librairies utilisées ainsi que la façon dont va être construite l’application.

Le but de ce chapitre n’est pas d’expliquer comment fonctionne Maven mais plutôt comment utiliser Maven avec un projet J2SE et JPA-Hibernate sous NetBeans.

1. NetBeans

a. Configuration

NetBeans inclut une version de Maven et permet d’en paramétrer une autre.

 L’accès à la configuration de Maven dans NetBeans se fait via le menu Tools - Options.

images/C8_1_01.png

 Une fois sur la fenêtre d’options, allez sur l’onglet Java, puis Maven :

images/C8_1_02.png

 Depuis l’onglet Execution de la liste Categories, il est possible de choisir la version de Maven à utiliser si la version embarquée par NetBeans (ici 3.0.5) n’est pas celle à utiliser :

images/C8_1_03.png

 Depuis l’onglet Dependencies de la liste Categories, il est possible de choisir la politique de téléchargement des fichiers binaires, de la JavaDoc et du code source des différentes dépendances (librairies Maven utilisées) :

images/C8_1_04.png

b. Création d’un projet

 Pour créer un projet Maven, cliquez sur le bouton qui permet...

Génération automatique

Afin de raccourcir le temps de développement, plusieurs outils de génération automatique existent :

  • La génération des entités : création des différentes entités depuis la base de données.

  • La génération de la base de données : création des tables depuis les entités. 

  • La génération du métamodèle : création du métamodèle depuis les entités. 

1. Génération des entités

La génération des entités depuis la base de données va permettre de créer toutes les entités voulues depuis une connexion à une base de données. Cela va permettre, depuis une base de données existante, de créer le modèle objet.

Ainsi, il est possible de sélectionner toutes les tables du schéma afin de générer une entité par table.

NetBeans propose ce type de génération en natif.

 Pour y accéder, faites un clic droit sur le projet, choisissez le menu New - Other.

images/C8_2_01.png

 Dans la catégorie Persistence, choisissez Entity Classes from Database.

images/C8_2_02.png

 Dans la partie Database Connection, choisissez la connexion à la base de données qui a servi pour créer le fichier de persistance (cf. section Paramétrage de l’ORM - Création du fichier persistence.xml du chapitre Préparation d’un projet).

images/C8_2_03.png

 Sélectionnez les différentes tables disponibles puis cliquez sur le bouton Add >.

images/C8_2_04.png

 Une fois les tables qui seront utilisées pour créer les entités sélectionnées, cliquez sur le bouton Next >.

images/C8_2_05.png

 Sur la fenêtre de création des entités, il est possible de les renommer dans le tableau Class Names. Saisissez le package des entités (ici com.eni.jpa.entity) puis les différentes options selon le besoin (ici NamedQuery qui va créer automatiquement les requêtes nommées sur chaque champ de l’entité, annotation JAXB qui ajoute les annotations JAXB au sein de l’entité pour une possible utilisation en webservice et création de l’unité de persistance) puis cliquez sur Next >.

images/C8_2_06.png

 Sur la page des options de mapping, choisissez celles voulues (ici...

Gestion des caches

1. Généralités

Il a été vu que JPA a deux niveaux de caches. Le cache L1 et le cache L2. Le cache L1 est au niveau des EntityManager et le cache L2 est au niveau de L’EntityManagerFactory.

C’est-à-dire que lors de la recherche d’une entité, l’ORM interroge le cache L1, s’il ne trouve pas cette entité, il interroge le cache L2, et s’il ne la trouve toujours pas, une requête est exécutée.

Par exemple, le code suivant montre les requêtes exécutées :


EntityManager em = ... 
int id = 1; 
System.out.println("------------ (premier find)"); 
Personne p = em.find(Personne.class, id); 
System.out.println(p); 
System.out.println("------------ (deuxième find)"); 
p = em.find(Personne.class, id); 
System.out.println(p); 
System.out.println("------------ (troisième find)"); 
EntityManager em2 = ... 
p = em2.find(Personne.class, id); 
System.out.println(p);
 

Ce qui apparaît dans la console :


------------ (premier find) 
Hibernate:  
    select 
        personne0_.id as id1_4_0_, 
        personne0_.date_naissance as date_nai2_4_0_, 
        personne0_.nom as nom3_4_0_, 
        personne0_.prenom as prenom4_4_0_, 
        personnede1_.id_personne as id_perso1_6_1_, 
        personnede1_.num_secu as num_secu2_6_1_, 
        personnede1_.sexe as sexe3_6_1_  
    from 
        personne personne0_  
    left outer join 
        personne_detail personnede1_  
            on personne0_.id=personnede1_.id_personne  
    where 
        personne0_.id=? 
com.eni.jpa.entity.Personne[ id=1 ] 
------------ (deuxième find) 
com.eni.jpa.entity.Personne[ id=1 ] 
------------ (troisième find) 
Hibernate:  
    select 
       ...

Les contrôles entre JPA et la base de données

L’utilisation de JPA permet principalement d’intervenir sur des données entre JPA et le code source. Il y a un lien fort entre la base de données, le modèle objet et les données.

1. Les EntityListener

Les EntityListener peuvent être apparentés à des déclencheurs. C’est-à-dire qu’ils vont agir sur les données à un moment précis de l’interaction entre la donnée du code source et la donnée persistée (dans le contexte de persistance et la base de données).

Pour cela il y a sept annotations possibles :

  • @PrePersist : avant qu’une nouvelle entité soit persistée.

  • @PostPersist : après la sauvegarde d’une nouvelle entité en base de données. 

  • @PostLoad : après le chargement de l’entité depuis la base de données dans le contexte de persistance.

  • @PreUpdate : quand une entité est identifiée comme modifiée par l’EntityManager

  • @PostUpdate : après la modification d’une entité sur la base de données (commit ou flush).

  • @PreRemove : quand une entité est identifiée comme supprimée par l’EntityManager

  • @PostRemove : après avoir supprimé une entité de la base de données (commit ou flush).

Ces annotations peuvent être placées directement sur une méthode d’une entité (comme montré à la section Création d’une entité - Création d’une arborescence d’entités du chapitre Manipulation des données) ou dans une classe qui sert de listener. Pour utiliser un listener une fois créé, il suffit de déclarer l’annotation @EntityListeners avec un tableau de classe de listener à utiliser.

Par exemple, pour remplacer l’annotation @PrePersist de l’entité PersonneDetail pour utiliser un listener...

Pool de connexions

Les pools de connexions permettent de : limiter le nombre de connexions simultanées aux données, gérer les connexions "fantômes" et vérifier que la connexion avec la base de données est toujours possible.

Hibernate a un gestionnaire de pool de connexions en natif : c3p0.

1. Installation

Pour installer c3p0, il suffit d’ajouter les jar au projet. Pour cela, deux façons :

  • Ajouter les librairies récupérées lors du téléchargement d’Hibernate :

images/C8_5_01.png
  • Ajouter la dépendance Maven depuis le repository d’Hibernate :


<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate-c3p0</artifactId> 
    <version>5.2.4.Final</version> 
</dependency>
 

2. Configuration

c3p0 est un outil extrêmement configurable qui possède beaucoup de paramètres modifiables. La liste complète des propriétés de c3p0 est trouvable à cette adresse : http://www.mchange.com/projects/c3p0/index.html#configuration_properties

Hibernate surcharge une partie de ses propriétés afin de pouvoir les configurer directement dans le fichier de persistance.

Ci-dessous, la liste des propriétés à ajouter au fichier de persistance :

  • hibernate.c3p0.timeout : le temps pendant lequel une connexion...

Divers

1. Affichage des requêtes

JPA n’a pas de propriété particulière pour afficher les requêtes exécutées, chaque implémentation a sa propre gestion d’affichage.

Pour Hibernate, il y a deux propriétés pour la gestion de cet affichage :

  • hibernate.show_sql : prend pour valeur true ou false et permet d’afficher ou non les requêtes exécutées. false par défaut.

  • hibernate.format_sql : prend pour valeur true ou false et permet de formater l’affichage des requêtes si elles sont à afficher. false par défaut.

Par exemple :

show_sql à faux et format_sql à vrai :


<property name="hibernate.show_sql" value="false" /> 
<property name="hibernate.format_sql" value="true"/>
 

N’affiche pas de requête.

show_sql à vrai et format_sql à faux (ou pas précisé) :


<property name="hibernate.show_sql" value="true" /> 
<property name="hibernate.format_sql" value="false"/>
 

Donne dans la console (sur une ligne) :


Hibernate: select personne0_.id as id1_4_0_, personne0_.date_naissance as  
date_nai2_4_0_, personne0_.nom as nom3_4_0_, personne0_.prenom as  
prenom4_4_0_, personnede1_.id_personne as id_perso1_6_1_,  
personnede1_.num_secu as num_secu2_6_1_, personnede1_.sexe as sexe3_6_1_  
from personne personne0_ left outer join personne_detail personnede1_...