69
Faculté des Sciences Dhar El Mahraz Master Qualité du Logiciel Rapport du projet de recherche Sous le thème Le Framework Hibernate Encadré par : Réalisé par : M. CHENFOUR Noureddine BOUSSAMAA Mohamed BRAHMI Youssef CHAIBI Sarra GARTANI Imane KAOUTAR Soumia SMILI Abdelhak Année Universitaire : 2014 - 2015

Rapport hibernate

Embed Size (px)

Citation preview

Page 1: Rapport hibernate

Faculté des Sciences Dhar El Mahraz

Master Qualité du Logiciel

Rapport du projet de recherche

Sous le thème

Le Framework Hibernate

Encadré par : Réalisé par :

M. CHENFOUR Noureddine BOUSSAMAA Mohamed

BRAHMI Youssef

CHAIBI Sarra

GARTANI Imane

KAOUTAR Soumia

SMILI Abdelhak

Année Universitaire : 2014 - 2015

Page 2: Rapport hibernate

- 1 -

Rapport du projet de recherche : Le framework Hibernate 1

Table des matières

Table des matières ............................................................................................................................. 1

Liste des figures ................................................................................................................................. 4

Introduction générale ....................................................................................................................... 5

Chapitre I : Présentation du framework Hibernate ................................................................... 6

1. Contexte du framework Hibernate ..................................................................................... 6

1.1. La persistance des objets ............................................................................................ 6

1.2. La problématique ........................................................................................................ 6

1.3. Solution : ORM ............................................................................................................ 7

1.4. Historique de l’ORM ................................................................................................... 7

2. Présentation de Hibernate .................................................................................................... 7

3. Historique des versions ........................................................................................................ 8

4. Caractéristiques générales .................................................................................................... 8

5. Architecture de Hibernate .................................................................................................... 9

5.1. Vue d’ensemble ........................................................................................................... 9

5.2. Architecture détaillée .................................................................................................. 9

Chapitre II : Environnement de développement et première application .......................... 11

1. L’IDE Eclipse ........................................................................................................................ 11

2. Installation ............................................................................................................................ 11

2.1. Les modules de Hibernate ....................................................................................... 12

2.2. Téléchargement de Hibernate ORM ....................................................................... 12

2.3. Installation de Hibernate .......................................................................................... 13

3. Hibernate Tools .................................................................................................................... 14

3.1. Présentation de Hibernate Tools ............................................................................. 14

3.2. Installation de Hibernate Tools ............................................................................... 14

3.3. Projet Hibernate avec Hibernate Tools .................................................................. 15

4. Première application ........................................................................................................... 19

Chapitre III : Le mapping ............................................................................................................. 22

1. Déclaration du mapping ..................................................................................................... 22

1.1. Le fichier de mapping Hibernate (hbm.xml) ......................................................... 22

1.2. Le mapping par annotations .................................................................................... 28

Page 3: Rapport hibernate

- 2 -

Rapport du projet de recherche : Le framework Hibernate 2

2. Le mapping des associations ............................................................................................. 30

2.1. Associations unidirectionnelles ............................................................................... 31

2.2. Associations unidirectionnelles avec tables de jointure ...................................... 32

2.3. Associations bidirectionnelles ................................................................................. 34

2.4. Associations bidirectionnelles avec tables de jointure ......................................... 36

3. Les entités persistées ........................................................................................................... 37

Chapitre IV : La Configuration .................................................................................................... 39

1. Configuration par programmation ................................................................................... 39

2. Configuration à travers le fichier hibernate.properties ................................................. 40

3. Configuration à travers un fichier de configuration XML ............................................ 40

4. Propriétés de configuration ................................................................................................ 41

5. SessionFactory ...................................................................................................................... 43

5.1. Description ................................................................................................................. 43

5.2. Création d’une instance SessionFactory ................................................................ 43

5.3. Méthodes de SessionFactory .................................................................................... 44

5.4. Connexion à plusieurs bases de données .............................................................. 44

Chapitre V : La persistance des objets ........................................................................................ 45

1. Session ................................................................................................................................... 45

2. Les méthodes de Session .................................................................................................... 45

3. Les états des objets .............................................................................................................. 45

4. Chargement des objets ........................................................................................................ 47

5. Rendre des objets persistants ............................................................................................. 47

6. Détacher des objets persistants .......................................................................................... 48

7. Mise à jour des données ...................................................................................................... 48

8. Suppression d'objets persistants ........................................................................................ 48

9. Flush de la session ............................................................................................................... 48

10. Les transactions ................................................................................................................. 49

Chapitre VI : Requêtage avec Hibernate ................................................................................... 51

1. Hibernate Query Language ............................................................................................... 51

2. L’API Criteria ....................................................................................................................... 53

2.1. L'interface org.hibernate.criterion.Criteria ............................................................ 54

2.2. L'interface org.hibernate.criterion.criterion ........................................................... 54

Page 4: Rapport hibernate

- 3 -

Rapport du projet de recherche : Le framework Hibernate 3

2.3. La classe org.hibernate.criterion.Restrictions ........................................................ 55

2.4. La classe org.hibernate.criterion.Projection ........................................................... 56

3. SQL natif ............................................................................................................................... 57

3.1. Requêtes scalaires ...................................................................................................... 57

3.2. Requêtes d’entités ...................................................................................................... 57

3.3. Requêtes de mise à jour des données ..................................................................... 57

3.4. Gestion des associations et des collections ............................................................ 58

3.5. Les paramètres ........................................................................................................... 59

Chapitre VI : Hibernate Validator .............................................................................................. 60

1. Principe ................................................................................................................................. 60

2. Description de Hibernate Validator .................................................................................. 61

3. Les contraintes intégrées .................................................................................................... 61

4. Déclaration et validation des contraintes ......................................................................... 63

5. Créer des contraintes personnalisées ................................................................................ 64

6. La composition des contraintes ......................................................................................... 66

Conclusion générale ........................................................................................................................ 67

Références ......................................................................................................................................... 68

Page 5: Rapport hibernate

- 4 -

Rapport du projet de recherche : Le framework Hibernate 4

Liste des figures

Figure 1. Représentation d'une architecture 3 tiers ..................................................................................................... 6

Figure 2. Logo du framework Hibernate ...................................................................................................................... 7

Figure 3. Historique des versions de Hibernate ORM ................................................................................................ 8

Figure 4. Une vue de haut niveau de l'architecture de Hibernate ............................................................................. 9

Figure 5. Architecture détaillé de Hibernate ................................................................................................................ 9

Figure 6. Capture du site de Hibernate ....................................................................................................................... 12

Figure 7. Répertoire après décompression du fichier téléchargé ............................................................................ 13

Figure 8. Les étapes d'installation de Hibernate Tools ............................................................................................. 15

Figure 9. Les étapes de création d'un fichier de configuration via Hibernate Tools ............................................. 17

Figure 10. Les étapes de la création d'une nouvelle configuration de Hibernate via Hibernate Tools .............. 17

Figure 11. Génération par Hibernate Tools des modèles de données et les fichiers de mapping ....................... 18

Figure 12. Classe modèle « Client » ............................................................................................................................. 19

Figure 13. Fichier du mapping du modèle « Client » ................................................................................................ 19

Figure 14. Configuration de la connexion à la base de données .............................................................................. 20

Figure 15. Classe utile pour la création et la récupération de l'objet de SessionFactory ...................................... 20

Figure 16. Classe « Test » et résultat de l’exécution ................................................................................................... 21

Figure 17. Arborescence du projet de test ................................................................................................................... 21

Figure 18. Structure générale du fichier de mapping ................................................................................................ 22

Figure 19. L'élément <hibernate-mapping> ............................................................................................................... 23

Figure 20. L'élément <class> ......................................................................................................................................... 24

Figure 21. L'élément <id> ............................................................................................................................................. 25

Figure 22. L'élément <property>.................................................................................................................................. 26

Figure 23. Classe persistante Produit .......................................................................................................................... 27

Figure 24. Le fichier de mapping produit.hbm.xml .................................................................................................. 28

Figure 25. Classe Produit mappée par annotations ................................................................................................... 29

Figure 26. Exemple de configuration par programmation ....................................................................................... 39

Figure 27. Exemple de configuration à travers le fichier hibernate.properties ...................................................... 40

Figure 28. Emplacement du fichier de configuration XML ...................................................................................... 40

Figure 29. Exemple d'un fichier de configuration XML ............................................................................................ 40

Figure 30. Changement des états d'objet en fonction des méthodes ....................................................................... 46

Figure 31. Exemple de la méthode load() ................................................................................................................... 47

Figure 32. Exemple de la méthode save() ................................................................................................................... 47

Figure 33. Cycle de vie d'une transaction ................................................................................................................... 49

Figure 34. Exemple de Criteria ..................................................................................................................................... 54

Figure 35. Exemple de requête scalaire ....................................................................................................................... 57

Figure 36. Exemple de requête d'entité ....................................................................................................................... 57

Figure 37. Exemple de requête Delete ......................................................................................................................... 58

Figure 38. Exemple de requête Update ....................................................................................................................... 58

Figure 39. Exemple de requête d'insertion ................................................................................................................. 58

Figure 40. Exemple de paramètre de position ............................................................................................................ 59

Figure 41. Exemple de paramètre nommé .................................................................................................................. 59

Figure 42. Principe de la validation classique ............................................................................................................ 60

Figure 43. Principe de la validation par Hibernate Validator .................................................................................. 60

Figure 44. Modèle Client annotés pour faire la validation ....................................................................................... 63

Figure 45. Exemple de la mise en œuvre de la validation ........................................................................................ 64

Figure 46. Exemple d'une contrainte personnalisée .................................................................................................. 64

Figure 47. Exemple d’implémentation d'un validateur de contrainte .................................................................... 65

Figure 48. Exemple d'utilisation de ConstraintValidatorContext ........................................................................... 65

Figure 49. Exemple de composition des contraintes ................................................................................................. 66

Page 6: Rapport hibernate

- 5 -

Rapport du projet de recherche : Le framework Hibernate 5

Introduction générale

Dans le monde des applications et des technologies, la manipulation des données constitue

un grand problème, qui se présente dans la synchronisation entre la partie applicatif et la

base de données. Donc, pour se libérer de ce problème, l'un des fondements de la

programmation consiste à trouver une solution au problème relatif à la persistance des

données.

La persistance des données est un mécanisme responsable des opérations de la sauvegarde

et de la restauration des données. Ce mécanisme fait en sorte qu'un programme puisse se

terminer sans que ses données et son état d'exécution ne soient perdus.

Pour bien assurer la persistance des données dans un environnement orienté objet, l’idéal

est d’utiliser une solution ORM (MAPPING OBJET RELATIONNEL). Son principe consiste

à déléguer l’accès aux données à des outils ou des frameworks externes. Son avantage est

de proposer une vue orienté objet d’une structure de données relationnelle (lignes et

colonnes).

Il existe plusieurs API et frameworks permettant de faire du mapping objet relationnel : les

entity beans, Hibernate, TopLink, JDO et JPA. Dans notre documentation nous allons

présenter la solution Hibernate.

Hibernate est un framework permettant la gestion de la persistance des objets en base de

données relationnelle. En d’autres termes, il nous laisse manipuler des objets qui sont liés

aux tables de notre base de données, facilitant ainsi l’accès (lecture, écriture, modification,

traitement) de celles-ci. Comme nous allons le voir, il est facile et rapide à mettre en place et

accélère toutes les tâches liées à la récupération et au traitement des données. Un autre

avantage d’Hibernate est qu’il fournit une couche d’abstraction supplémentaire (en passant

par son propre langage SQL : HQL), permettant de s’abstraire du type de SGBD utilisé

(MySQL, Oracle, Microsoft SQL Server, ...).

Page 7: Rapport hibernate

- 6 -

Rapport du projet de recherche : Le framework Hibernate 6

Présentation du framework

Hibernate

1. Contexte du framework Hibernate

1.1. La persistance des objets

A la fin d’une session d’utilisation d’une application orientée objet toutes les données des

objets existant dans la mémoire vive de l’ordinateur sont perdues. Pour rendre un objet

persistant, il est requis de sauvegarder ses données sur un support non volatile de telle sorte

qu’un objet identique à cet objet pourra être recréé lors d’une session ultérieure.

La persistance des objets est un point critique, dont dépendent la performance et la

disponibilité des données de tout projet Java.

1.2. La problématique

Dans une architecture 3-tiers, les responsabilités sont séparées :

− La couche présentation regroupe tout ce qui a trait à la présentation des données et

aux interactions avec l’utilisateur, en appelant des traitements mis à disposition sous

forme de méthode par les objets métier.

− La couche métier ne doit contenir que la logique métier, c’est à dire propre à l’objet

qu’elle représente.

− La couche DAO (Data Access Objects) a pour but de transformer les objets métiers

en données sérialisées et inversement.

Pour assurer la persistance des données des objets, les développeurs ont souvent recours à

stocker les données dans des bases de données relationnelles (les SGBD relationnelles

dominent le marché) à travers l’utilisation de JDBC, ce qui exige :

Figure 1. Représentation d'une architecture 3 tiers

I

Page 8: Rapport hibernate

- 7 -

Rapport du projet de recherche : Le framework Hibernate 7

− Connaître au préalable la structure de la base de données pour faire le mapping entre

les tables et les objets ;

− Maintenir la connexion avec la base de données ;

− Implémenter les mécanismes d’interaction avec la base de données ;

Donc, faire correspondre le modèle de développement orienté-objet au modèle de données

relationnel serait au détriment de la flexibilité des données et de la performance,

certainement lorsqu’il s’agit d’une application d’entreprise. D’autre part, le développement

devient fastidieux et par conséquent un coût nettement élevé.

1.3. Solution : ORM

Pour pallier à cette problématique, il faut s’affranchir de la forme brute des données en

utilisant les solutions ORM (object-relational mapping). Parmi les avantages d’un ORM :

− Gain de temps au niveau du développement d’une application ;

− Gain important de performance grâce aux mécanismes avancés de cache ;

− Pas besoin de connaître l’ensemble des tables et des champs de la base de données ;

− Abstraction de toute la partie SQL d’une application ;

− La portabilité de l’application d’un point de vue SGBD ;

1.4. Historique de l’ORM

L’apparition de l’ORM a eu lieu en 1994, et n’a pas cessé d’évoluer :

› 1994 : TopLink, premier ORM au monde, en SmallTalk (langage de développement) ;

› 1996 : TopLink propose une version JAVA ;

› 1998 : EJB 1.0 ;

› 2000 : EJB 2.0 ;

› 2001 : Lancement d’Hibernate, afin de proposer une alternative aux EJB 2.0 ;

› 2006 : EJB 3.0 et JPA 1.0 ;

› 2007 : TopLink devient EclipseLink ;

› 2009 : JPA 2.0 ;

› 2013 : JPA 2.1 ;

2. Présentation de Hibernate

Hibernate est un framework open source gérant la

persistance des objets en base de données relationnelle. Il a

été développé en 2001 par un groupe de développeurs

Java dirigés par Gavin King. Leur objectif principal était

d'offrir de meilleures capacités en persistance que celles proposées par EJB 2.0 en simplifiant

ses complexités et complétant les fonctionnalités manquantes.

Figure 2. Logo du framework Hibernate

Page 9: Rapport hibernate

- 8 -

Rapport du projet de recherche : Le framework Hibernate 8

Hibernate apporte une solution aux problèmes d'adaptation entre le paradigme objet et les

SGBD en remplaçant les accès à la base de données par des appels à des méthodes objet de

haut niveau.

3. Historique des versions

Hibernate a été développé par un groupe de développeurs Java dirigés par Gavin King.

L'entreprise JBoss (maintenant une division de RedHat) a embauché les développeurs

principaux d'Hibernate et a travaillé avec eux afin de maintenir et développer le produit.

Le schéma suivant montre le développement des versions d’Hibernate en fonction du

temps :

4. Caractéristiques générales

Parmi les caractéristiques de Hibernate, nous trouvons :

› Optimisation du temps de développement du programmeur ;

› Des applications facilement migrables (pour changer de base de données, il suffit

d’intervenir au niveau du fichier de configuration hibernate.cfg.xml) ;

› Hibernate génère le code SQL nécessaire ;

› Hibernate fournit un langage de requête HQL, indépendamment du type de la base

de données ;

› Interroger la base de données de plusieurs façon (Requête SQL, langage HQL...) ;

› La récupération des données est optimisée ;

Figure 3. Historique des versions de Hibernate ORM

Page 10: Rapport hibernate

- 9 -

Rapport du projet de recherche : Le framework Hibernate 9

5. Architecture de Hibernate

5.1. Vue d’ensemble

L’architecture de Hibernate est découpée en couche

afin d’isoler les utilisateurs des API qui le constitue.

Hibernate utilise la base de données et la

configuration (mapping et configuration) pour

fournir à l’application un service de persistance et

des objets persistants.

5.2. Architecture détaillée

L’architecture (ci-dessus) est plus complète, elle abstrait l'application des APIs JDBC/JTA

sous-jacentes et laisse Hibernate s'occuper des détails.

Figure 4. Une vue de haut niveau de l'architecture de Hibernate

Figure 5. Architecture détaillé de Hibernate

Page 11: Rapport hibernate

- 10 -

Rapport du projet de recherche : Le framework Hibernate 10

Les éléments qui constituent cette architecture :

› Configuration Object :

- La connexion avec la base de données : qui contient un fichier de configuration

(Hibernate properties ou Hibernate.cfg.xml).

- Les classes de mapping : à travers eux que nous pouvons créer la connexion

avec la base de données.

› SessionFactory Object : c’est la factory des instances des Session, et il est en générale

unique par application (excepte dans le cas où l’application gère plusieurs bases de

données, il y aura une SessionFactory par base de données) cette interface est loin

d’être légère car elle est aussi responsable de gérer tous les métadonnées liées au

mapping objet/relationnel, la mise en cache des instructions SQL et contenir le cache

des entités utilisées par l’application cliente. Elle est aussi ce que l’on appelle thread-

safe, cela veut dire qu’elle peut être partagée entre de nombreux threads de

l’application.

› Session Object : C’est un objet léger de courte durée qui permet de crée la connexion

physique avec la base de donnée.

› Transaction Object : Il présente une unité de travaille avec la base de donnée.

› Query Object : Il utilise SQL ou HQL (Hibernate Query Language) pour récupérer

les données de la base de données et créé les objets.

› Criteria Object : Permet de crée et d’exécuter les requêtes.

› La couche de la base de données : Permet de récupérer et de stocker les données à

partir d’une base de données.

› Interfaces d'extension : Hibernate fournit de nombreuses interfaces d'extensions

optionnelles que vous pouvez implémenter pour personnaliser le comportement de

votre couche de persistance. Ces APIs sont :

- JTA : JAVA Transaction API.

- JNDA : JAVA Naming and Directory interface.

- JDBC : JAVA DataBase Connectivity, fournit un niveau primitif de l’abstraction

des fonctionnalités commun aux bases de données relationnel, ce qui permet

presque à n’importe qu’elle base de données avec un pilot JDBC d’être prise en

charge avec Hibernate.

- JNDI et JTA permet à Hibernate d’être intégré avec les serveurs d'applications

J2EE.

Page 12: Rapport hibernate

- 11 -

Rapport du projet de recherche : Le framework Hibernate 11

Environnement de développement et

première application

1. L’IDE Eclipse

Eclipse est un projet, décliné et organisé en un ensemble de sous-projets de développements

logiciels, de la Fondation Eclipse visant à développer un environnement de production de

logiciels libre qui soit extensible, universel et polyvalent, en s'appuyant principalement sur

Java.

Eclipse permet le développement d'applications Java principalement, mais également

d'autres langages grâce à l'utilisation de plugins.

Eclipse est une plateforme de développement écrite en Java, fruit du travail d'un consortium

de grandes entreprises (IBM, Borland, Rational Rose, HP...). Il en résulte un IDE performant

et open Source qui a su trouver sa place comme l'un des IDE Java les plus populaires.

Au niveau ergonomie, Eclipse n'a rien à envier à ses concurrents. Toutes les fonctionnalités

indispensables sont là : création de projet, de Template, refactoring, débogage... et

remarquablement faciles à prendre en main. Mais la grande force de cet IDE réside dans

l'ouverture de son noyau qui permet l'ajout de très nombreux plugins. Il est par exemple

possible d'intégrer des éditeurs XML, HTML, JSP, etc. ou encore de déployer ses

applications vers la quasi-totalité des serveurs du marché.

2. Installation

Pour préparer l’environnement du travail, nous devons nous rendre sur le site du projet

Hibernate : http://hibernate.org/

II

Page 13: Rapport hibernate

- 12 -

Rapport du projet de recherche : Le framework Hibernate 12

2.1. Les modules de Hibernate

Le site de Hibernate présente les différents modules de Hibernate :

› Hibernate ORM : module principal pour le mapping Objet / Relationnel ;

› Hibernate Search : moteur de recherche texte ;

› Hibernate Validator : implémentation de JSR 303 : Bean Validation ;

› Hibernate OGM : permet le mapping entre objets et base NoSQL ;

› Hibernate Tools : boîte à outils du développeur Hibernate (version Eclipse ou ANT) ;

2.2. Téléchargement de Hibernate ORM

Pour installer Hibernate ORM, nous devons d’abord télécharger le module correspondant

sur l’adresse suivante : http://hibernate.org/orm/downloads/

Sur cette adresse, nous allons trouver différentes versions du module. Nous avons choisi

de travailler en utilisant la version 4.3.8 (voir le livrable).

* Il est possible de ne pas trouver sur le site la version que vous cherchez, ceci est dû au

développement continu du module Hibernate ORM. Pour trouver les anciennes versions, rendez-

vous sur cette adresse : http://sourceforge.net/projects/hibernate/files/hibernate-orm/

Figure 6. Capture du site de Hibernate

Page 14: Rapport hibernate

- 13 -

Rapport du projet de recherche : Le framework Hibernate 13

2.3. Installation de Hibernate

Après la décompression du fichier téléchargé, on aura la structure du répertoire comme

suit :

Les librairies que nous trouvons :

› Antlr : (ANother Tool for Language Recognition) est un outil permettant de

développer un langage maison avec une grammaire capable de le reconnaître. Utilisé

pour créer langage HQL (Hibernate Quercy Language) - Indispensable à l’exécution.

› Dom4j : est une API Open Source Java permettant de travailler avec XML, XPath et

XSLT.

› Hibernate-commons-annotations : utilisé pour annotation JPA.

› Hibernate-core : est une bibliothèque de mapping objet/relationnel, permettant aux

applications d'éviter une interaction directe avec la base de données.

› Hibernate-jpa : Java Persistence API.

› Jandex : (Java Annotation Indexer) est un outil qui traite les annotations.

› Javassist : est une API de manipulation de Bytecode (fichier .class), dans un contexte

de réflexion, c’est à dire de modification du contenu d’une classe en phase

d’exécution.

› Jboss-logging : procure un moyen facile d'ajouter une journalisation à votre

application.

› Jboss-transaction : est une plate-forme de gestion de transactions distribuées pour

Java EE, CORBA et les applications de services Web.

Pour commencer à utiliser Hibernate, il suffit d’associer ces librairies au build-path de

votre projet.

Figure 7. Répertoire après décompression du fichier téléchargé

Page 15: Rapport hibernate

- 14 -

Rapport du projet de recherche : Le framework Hibernate 14

3. Hibernate Tools

3.1. Présentation de Hibernate Tools

C’est l’un des projets qui composent la sphère d’Hibernate .C’est un ensemble d’outils et de

plug-in pour ANT et Eclipse facilitant le développement avec Hibernate.

L’outil de Hibernate contient plusieurs fonctionnalités disponibles sous Eclipse, ces

fonctionnalités sont :

− Mapping Editor : Editeur de mapping : simplifier l’écriture des fichiers de mapping et

il applique un jeu de couleurs en fonction des éléments du fichier XML. Il permet

aussi l’auto complétion des nœuds, des noms de classes et des propriétés.

− Hibernate Console : cette perspective permet de configurer la connexion de la base de

données, aussi de visualiser des classes et leurs relations d'exécuter les requêtes HQL et

parcourir ces résultats.

− Reverse Engineering : consiste à exploiter un schéma de base de données existante et

permet d’effectuer les tâches suivantes :

o génération de métadonnées depuis un schéma de base de données existant

o génération de vos fichiers de mapping et de vos sources Java ;

o génération directe de vos sources Java complétées d’annotations

(expérimentales).

− ANT task (génération et exploitation de code) : Hibernate Tools propose plusieurs

assistants de généralisation, ces assistants peuvent être exécutés depuis Eclipse ou via

une tâche ANT, cette tâche permet d’exploiter les métadonnées.

3.2. Installation de Hibernate Tools

Nous expliquons montre les étapes mentionnées sur l’image ci-dessous pour installer

Hibernate Tools sur l’IDE Eclipse :

1) Hibernate Tools fait partie du plugin JBoss Tools que nous pouvons installer à travers

le Marketplace d’Eclipse, il suffit de taper JBoss et cliquer sur installer qui correspond

à JBoss Tools ;

2) Une nouvelle fenêtre s’affiche pour choisir les plugins à installer, nous cochons

Hibernate Tools ;

3) Une fois l’installation est terminée, nous pouvons ouvrir la perspective Hibernate

Tools pour accéder à toutes ses fonctionnalités ;

Page 16: Rapport hibernate

- 15 -

Rapport du projet de recherche : Le framework Hibernate 15

3.3. Projet Hibernate avec Hibernate Tools

Pour créer un projet en utilisant Hibernate Tools, nous allons suivre ces étapes (Cf. images

ci-dessous) :

1) Nous créons un projet normal ;

› Création d’une configuration Hibernate :

2) Nous basculons vers la perspective Hibernate, puis nous associons une configuration de

Hibernate à notre projet ;

3) Dans la fenêtre, nous donnons un nom à la configuration (pour pouvoir l’exploiter une

autre fois) :

a. Nous choisissons le type d’utilisation de Hibernate : Core, Annotations ou JPA ;

b. Nous choisissons le projet auquel nous allons associer cette configuration ;

c. Nous allons choisir une connexion à une base de données s’elle existe déjà, sinon

nous allons configurer une nouvelle connexion ;

4) Pour configurer une nouvelle connexion à une base de données, nous fournissons les

propriétés de la connexion : nom de la base de données, url de la connexion, le nom

Figure 8. Les étapes d'installation de Hibernate Tools

Page 17: Rapport hibernate

- 16 -

Rapport du projet de recherche : Le framework Hibernate 16

d’utilisateur, le mot de passe, ...etc. Puis, nous testons si la connexion a abouti à travers

le bouton « Test connection » ;

› Création d’un fichier de configuration hibernate.cfg.xml :

5) Pour créer un fichier de configuration Hibernate, nous cliquons sur « Setup » de

configuration file, puis « Create new » ;

6) Une nouvelle fenêtre s’affiche qui nous demande les informations de la connexion à la

base de données. Mais puisque cette étape est déjà faite, lors de l’étape 4, il suffit de

cliquer sur « Get value from connection », nous choisissons la connexion et nous

validons ;

7) Après la création du fichier de configuration, nous observons dans l’arborescence le

contenu de la base de données ;

› Génération des modèles de données et les fichiers de mapping correspondants :

8) A titre d’exemple nous allons utiliser Hibernate Tools pour générer nos classes et leurs

fichiers de mapping : nous cliquons sur Hibernate Code Generation Configuration ;

9) Nous précisons après le projet sur lequel nous allons travailler, le package et la stratégie

à suivre lors de la création des classes model. Il ne faut pas oublier de cocher « Reverse

engineer from JDBC connection » ;

10) Nous sélectionnons les éléments à générer : les classes modèles et les fichiers de

mapping. Nous constatons dans l’arborescence les fichiers générés ;

11) Les classes modèles sont générées. elles implémentent la classe Serializable, chose qui

n’est pas obligatoire ;

12) Les fichiers de mapping générés font la correspondance entre les modèles de données et

la table correspondante dans la base de données ;

Page 18: Rapport hibernate

- 17 -

Rapport du projet de recherche : Le framework Hibernate 17

Figure 10. Les étapes de la création d'une nouvelle configuration de Hibernate via Hibernate Tools

Figure 9. Les étapes de création d'un fichier de configuration via Hibernate Tools

Page 19: Rapport hibernate

- 18 -

Rapport du projet de recherche : Le framework Hibernate 18

Figure 11. Génération par Hibernate Tools des modèles de données et les fichiers de mapping

Page 20: Rapport hibernate

- 19 -

Rapport du projet de recherche : Le framework Hibernate 19

4. Première application

Nous allons créer un nouveau projet où nous spécifions les étapes nécessaires pour mettre

en œuvre le framework Hibernate.

− Premièrement, nous créons un projet Java ordinaire sous Eclipse ;

− Nous créons un dossier lib où nous importons les librairies de Hibernate (Cf. Installation

de Hibernate) ;

− Nous créons par la suite, une classe modèle « Client » ;

− Après, nous allons créer un fichier de mapping (Cf. Chapitre de la configuration), où

nous faisons le mapping des propriétés du modèle « Client » ;

Figure 12. Classe modèle « Client »

Figure 13. Fichier du mapping du modèle « Client »

Page 21: Rapport hibernate

- 20 -

Rapport du projet de recherche : Le framework Hibernate 20

− Nous configurons la connexion à la base de données (Cf. Chapitre de la configuration),

où nous allons spécifier les propriétés de la connexion à la base de données ;

− Nous devons par la suite créer une classe qui nous sera utile pour la création et la

récupération d’un objet SessionFactory (Cf. Chapitre de la configuration) ;

Figure 14. Configuration de la connexion à la base de données

Figure 15. Classe utile pour la création et la récupération de l'objet de SessionFactory

Page 22: Rapport hibernate

- 21 -

Rapport du projet de recherche : Le framework Hibernate 21

− Enfin, nous créons une classe de test pour s’assurer du bon fonctionnement de

Hibernate ;

− Vers la fin, nous obtenons l’arborescence du projet suivante :

Figure 16. Classe « Test » et résultat de l’exécution

Figure 17. Arborescence du projet de test

Page 23: Rapport hibernate

- 22 -

Rapport du projet de recherche : Le framework Hibernate 22

Object Relationnel Mapping

(le mapping)

Hibernate doit savoir comment sauvegarder et charger les objets persistants, aussi faire la

correspondance entre les types SQL et les types Java. C’est le rôle des approches de mapping

de Hibernate.

1. Déclaration du mapping

Le mapping peut être définit sous deux formes, en utilisant :

− Les fichiers de mapping XML Hibernate connu sous le nom : hbm.xml ;

− Les annotations ;

1.1. Le fichier de mapping Hibernate (hbm.xml)

1.1.1. Structure générale du fichier de mapping

Un fichier de mapping est un fichier au format XML qui va contenir des informations sur la

correspondance entre la classe à persister et la table de la base de données.

Le nom de fichier de mapping doit se terminer par « .hbm.xml » pour que Hibernate sache

que c'est un fichier de mapping. De plus, par convention, on écrit un fichier de mapping par

classe de persistance.

Figure 18. Structure générale du fichier de mapping

III

Page 24: Rapport hibernate

- 23 -

Rapport du projet de recherche : Le framework Hibernate 23

1.1.2. L’élément <hibernate-mapping>

Il constitue l’élément racine de fichier de mapping, il peut contenir un ou plusieurs éléments

<class>, cependant il est préférable de n'utiliser qu'un seul élément <class> et de définir

autant de fichiers de correspondance que de classes.

− schema (optionnel) : Le nom d'un schéma de base de données.

− catalog (optionnel) : Le nom d'un catalogue de base de données.

− default-access (optionnel - par défaut vaut : property) : Définit comment hibernate

accèdera aux propriétés. On peut aussi redéfinir sa propre implémentation de

PropertyAccessor.

− default-cascade (optionnel - par défaut vaut : none) : Le type de cascade par défaut.

− default-lazy (optionnel - par défaut vaut : true) : La valeur par défaut pour un attribut

lazy non spécifié : celui des mappings de classes et de collection.

− auto-import (optionnel - par défaut vaut : true) : Spécifie si l'on peut utiliser des noms

de classes non qualifiés (des classes de ce mapping).

− package (optionnel) : Préfixe de package par défaut pour les noms de classe non qualifiés

du document de mapping.

<hibernate-mapping

schema = "..."

catalog = "..."

default-cascade = "..."

default-access = "field|property|ClassName"

default-lazy = "true|false"

auto-import = "true|false"

package = "..."

/>

Figure 19. L'élément <hibernate-mapping>

Page 25: Rapport hibernate

- 24 -

Rapport du projet de recherche : Le framework Hibernate 24

1.1.3. L’élément <class>

L’élément <class> permet de préciser des informations de mapping d’une classe d’entités

persistantes vers une table de la base de données SQL.

− name (obligatoire) : nom pleinement qualifié de la classe ;

− table (optionnel) : nom de la table dans la base de données, par défaut le nom non-

qualifié de la classe ;

− dynamic-update (optionnel) : booléen qui indique de ne mettre à jour que les champs

dont la valeur a été modifiée (false par défaut) ;

− dynamic-insert (optionnel) : booléen qui indique de ne générer un ordre insert que

pour les champs dont la valeur est non nulle (false par défaut) ;

− mutable (optionnel) : booléen qui indique si les occurrences peuvent être mises à jour

(true par défaut) ;

* Les classes immuables, mutable="false", ne peuvent pas être modifiées ou supprimées par

l'application. Cela permet à Hibernate de faire quelques optimisations mineures sur les

performances.

<class

name = "ClassName"

table = "tableName"

mutable = "true|false"

dynamic-update = "true|false"

dynamic-insert = "true|false"

/>

Figure 20. L'élément <class>

Page 26: Rapport hibernate

- 25 -

Rapport du projet de recherche : Le framework Hibernate 25

1.1.4. L’élément <id>

C’est l’élément fils de <class> permet de fournir des informations sur l'identifiant d'une

occurrence dans la table.

− name (optionnel) : nom de la propriété dans la classe

− type (optionnel) : le type Hibernate

− column (optionnel) : le nom du champ dans la base de données (par défaut le nom

de la propriété)

− unsaved-value (optionnel) : permet de préciser la valeur de l'identifiant pour une

instance non encore enregistrée dans la base de données. Les valeurs possibles sont :

any, none, null ou une valeur fournie. Null est la valeur par défaut.

* Si l'attribut name est absent, Hibernate considère que la classe ne possède pas de propriété

identifiant.

* L'attribut unsaved-value est important ! Si l'identifiant de votre classe n'a pas une valeur par

défaut compatible avec le comportement standard de Java (zéro ou null), vous devez alors

préciser la valeur par défaut.

− L’élément <generator> (obligatoire) : l’élément fils du <id>, permet de préciser quel

est le mode de génération d'un nouvel identifiant. Ce tag possède un seul attribut :

+ class (obligatoire) : précise la classe qui va assurer la génération de la valeur

d'un nouvel identifiant. Il existe plusieurs classes fournies en standard par

Hibernate qui possèdent un nom utilisable comme valeur de cet attribut.

* Assinged est la stratégie par défaut si aucun <generator> n'est spécifié.

<id

name = "propertyName"

type = "typename"

column = "column_name"

unsaved-value = "null|any|none|undefined|id_value"

access = "field|property|ClassName"

>

<generator class="generatorClass"/>

</id>

Figure 21. L'élément <id>

Page 27: Rapport hibernate

- 26 -

Rapport du projet de recherche : Le framework Hibernate 26

Les classes de génération fournies en standard par Hibernate possèdent chacun un nom :

increment Incrémentation d'une valeur dans la JVM.

identity Utilisation d'un identifiant auto-incrémenté pour les bases de données

qui le supportent (DB2, MySQL, SQL Server, ...).

sequence Utilisation d'une séquence pour les bases de données qui le supportent

(Oracle, DB2, PostgreSQL, ...).

hilo Utilisation d'un algorithme qui utilise une valeur réservée pour une

table d'une base de données (par exemple une table qui stocke la valeur

du prochain identifiant pour chaque table).

seqhilo Idem mais avec un mécanisme proche d'une séquence.

uuid.hex Utilisation d'un algorithme générant un identifiant de type UUID sur 32

caractères prenant en compte entre autres l'adresse IP de la machine et

l'heure du système.

uuid.string Idem générant un identifiant de type UUID sur 16 caractères.

native Utilise la meilleure solution proposée par la base de données.

assigned La valeur est fournie par l'application.

foreign La valeur est fournie par un autre objet avec lequel la classe est associée.

1.1.5. L’élément <property>

Le tag <property>, descendant du tag <class>, permet de fournir des informations sur une

propriété et sa correspondance avec un champ dans la base de données.

− name (obligatoire) : précise le nom de la propriété ;

− type (optionnel) : précise le type ;

− column (optionnel) : précise le nom du champ dans la base de données (par défaut

le nom de la propriété) ;

− update (optionnel) : précise si le champ est mis à jour lors d'une opération SQL de

type update (par défaut true) ;

<property

name = "propertyName"

column = "column_name"

type = "typename"

update = "true|false"

insert = "true|false"

/>

Figure 22. L'élément <property>

Page 28: Rapport hibernate

- 27 -

Rapport du projet de recherche : Le framework Hibernate 27

− insert (optionnel) : précise si le champ est mis à jour lors d'une opération SQL de

type insert (par défaut true) ;

* Si vous n'indiquez pas un type, Hibernate utilisera la réflexion sur le nom de la propriété pour

tenter de trouver le type Hibernate correct. Hibernate essayera d'interpréter le nom de la classe

retournée par le getter de la propriété.

1.1.6. Exemple de fichier de mapping

Nous voulons faire le mapping de la classe persistante Produit vers la table PRODUIT

Nous créons le fichier de mapping qui portera le nom : produit.hbm.xml et qui doit être

placé dans le même répertoire de la classe produit. Ce fichier fera la correspondance entre

la classe Produit et la table PRODUIT.

* Le fichier de mapping doit être situé dans le même répertoire que la classe correspondante

Figure 23. Classe persistante Produit

Page 29: Rapport hibernate

- 28 -

Rapport du projet de recherche : Le framework Hibernate 28

1.2. Le mapping par annotations

Le mapping par annotation est la méthode la plus récente pour faire le mapping, nous

pouvons utiliser les annotations pour compléter les fichiers de mapping XML ou carrément

pour les remplacer.

Les annotations sont basées sur la spécification JPA 2 et ils supportent toutes fonctionnalités

qu’offre un fichier de mapping. Et donc, nous bénéficions du fait qu’il n’est plus nécessaire

de créer un fichier de mapping XML, il suffit d’annoter la classe au moment de sa création.

Les annotations peuvent être divisées en deux catégories :

− Les annotations de mapping logique (permettant de décrire le modèle objet, les

associations de classes, etc.).

− Les annotations de mapping physique (décrivant le schéma physique, les tables, les

colonnes, les index, etc.).

Figure 24. Le fichier de mapping produit.hbm.xml

Page 30: Rapport hibernate

- 29 -

Rapport du projet de recherche : Le framework Hibernate 29

Le tableau suivant donne une brève description de certaines annotations :

@Entity Marque les entités Bean

@Table Spécifie le nom de la table dans la base de données

@Column Spécifie le nom de la colonne dans la base de données

@Id Mappe la propriété et la spécifie comme clé primaire

@GeneratedValue

Permet l’auto-génération de la clé dans la base de données

@OrderBy Permet de trier les données

@Version Permet d’ajouter la capacité de verrouillage à une entité bean

@Transient Permet de ne pas mapper une propriété, en ajoutant cette annotation sur le getter ou le setter de la propriété

@Basic L'annotation Basic vous permet de déclarer la stratégie de récupération pour une propriété

Figure 25. Classe Produit mappée par annotations

Page 31: Rapport hibernate

- 30 -

Rapport du projet de recherche : Le framework Hibernate 30

@Lob Annote les objets larges

@EmbeddedId Mappe les clés primaires composées

@Embeddable Surcharger le mapping d’une colonne d'un objet embarqué pour une entité particulière.

@AttributeOverride

Spécifier un autre nom d’une colonne d’une entité, il possède les attributs :

− name : on lui associer le nouveau nom. − column : avec l’annotation @Column on lui donne

l’ancien nom de la propriété.

@PrimaryKeyJoinColumn Associer les entités qui ont la même clé primaire

Nous ajoutons par la suite la balise mapping dans le fichier hibernate.cfg.xml pour spécifie la classe mappée.

2. Le mapping des associations

Autoriser une clé étrangère nulle est considéré comme un mauvais choix dans la

construction d'un modèle de données. Pour cela, nous devons exprimer les associations

entre les différents modèles de données.

Les associations sont divisées en plusieurs catégories :

− Associations unidirectionnelles ;

− Associations unidirectionnelles avec tables de jointure ;

− Associations bidirectionnelles ;

− Associations bidirectionnelles avec tables de jointure ;

Page 32: Rapport hibernate

- 31 -

Rapport du projet de recherche : Le framework Hibernate 31

2.1. Associations unidirectionnelles

2.1.1. Plusieurs-à-un

Une association plusieurs-à-un unidirectionnelle est le type que l'on rencontre le plus

souvent dans les associations unidirectionnelles.

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

<many-to-one name="address" column="addressId" not-null="true"/>

</class>

<class name="Address">

<id name="id" column="addressId">

<generator class="native"/>

</id>

</class>

create table Person (

personId int not null primary key,

addressId int not null

)

create table Address (addressId int not null primary key)

2.1.2. Un-à-un

Une association un-à-un sur une clé étrangère est presque identique. La seule différence est

sur la contrainte d'unicité que l'on impose à cette colonne.

<many-to-one

name="address"

column="addressId"

unique="true"

not-null="true"

/>

Page 33: Rapport hibernate

- 32 -

Rapport du projet de recherche : Le framework Hibernate 32

2.1.3. Un-à-plusieurs

Une association un-à-plusieurs unidirectionnelle sur une clé étrangère est un cas inhabituel,

et n'est pas vraiment recommandée. Il est préférable d'utiliser une table de jointure pour ce

type d'association.

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

<set name="addresses">

<key column="personId" not-null="true"/>

<one-to-many class="Address"/>

</set>

</class>

<class name="Address">

<id name="id" column="addressId">

<generator class="native"/>

</id>

</class>

create table Person ( personId int not null primary key )

create table Address (

addressId int not null primary key,

personId int not null

)

2.2. Associations unidirectionnelles avec tables de jointure

2.2.1. Un-à-plusieurs

Une association unidirectionnelle un-à-plusieurs avec une table de jointure est un bien

meilleur choix. Remarquez qu'en spécifiant unique="true", on a changé la multiplicité

plusieurs-à-plusieurs pour un-à-plusieurs.

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

Page 34: Rapport hibernate

- 33 -

Rapport du projet de recherche : Le framework Hibernate 33

<set name="addresses" table="PersonAddress">

<key column="personId"/>

<many-to-many column="addressId" unique="true" class="Address"/>

</set>

</class>

<class name="Address">

<id name="id" column="addressId">

<generator class="native"/>

</id>

</class>

create table Person ( personId int not null primary key )

create table PersonAddress (

personId int not null,

addressId int not null primary key

)

create table Address ( addressId int not null primary key )

2.2.2. Plusieurs-à-un

Une association plusieurs-à-un unidirectionnelle sur une table de jointure est assez

fréquente quand l'association est optionnelle.

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

<join table="PersonAddress" optional="true">

<key column="personId" unique="true"/>

<many-to-one name="address" column="addressId" not-null="true"/>

</join>

</class>

<class name="Address">

<id name="id" column="addressId">

<generator class="native"/>

</id>

</class>

Page 35: Rapport hibernate

- 34 -

Rapport du projet de recherche : Le framework Hibernate 34

create table Person ( personId int not null primary key )

create table PersonAddress (

personId int not null primary key,

addressId int not null

)

create table Address ( addressId int not null primary key )

2.2.3. Plusieurs-à-plusieurs

Un exemple d'association unidirectionnelle plusieurs-à-plusieurs :

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

<set name="addresses" table="PersonAddress">

<key column="personId"/>

<many-to-many column="addressId" class="Address"/>

</set>

</class>

<class name="Address">

<id name="id" column="addressId">

<generator class="native"/>

</id>

</class>

create table Person ( personId int not null primary key )

create table PersonAddress (

personId int not null,

addressId int not null,

primary key (personId, addressId)

)

create table Address ( addressId int not null primary key )

2.3. Associations bidirectionnelles

2.3.1. Un-à-plusieurs / Plusieurs-à-un

Une association bidirectionnelle plusieurs-à-un est le type d'association que l'on rencontre

le plus fréquemment. L'exemple suivant illustre la façon standard de créer des relations

parents/enfants.

Page 36: Rapport hibernate

- 35 -

Rapport du projet de recherche : Le framework Hibernate 35

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

<many-to-one name="address" column="addressId" not-null="true"/>

</class>

<class name="Address">

<id name="id" column="addressId">

<generator class="native"/>

</id>

<set name="people" inverse="true">

<key column="addressId"/>

<one-to-many class="Person"/>

</set>

</class>

create table Person (

personId int not null primary key,

addressId bigint not null

)

create table Address ( addressId bigint not null primary key )

2.3.2. Un-à-un

Une association bidirectionnelle un-à-un sur une clé étrangère est assez fréquente :

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

<many-to-one

name="address"

column="addressId"

unique="true"

not-null="true"/>

</class>

<class name="Address">

Page 37: Rapport hibernate

- 36 -

Rapport du projet de recherche : Le framework Hibernate 36

<id name="id" column="addressId">

<generator class="native"/>

</id>

<one-to-one name="person" property-ref="address"/>

</class>

create table Person (

personId int not null primary key,

addressId int not null unique

)

create table Address ( addressId int not null primary key )

2.4. Associations bidirectionnelles avec tables de jointure

2.4.1. Un-à-plusieurs / Plusieurs-à-un

Remarquez que inverse="true" peut s'appliquer sur les deux extrémités de l'association, sur

la collection, ou sur la jointure.

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

<set name="addresses" table="PersonAddress">

<key column="personId"/>

<many-to-many column="addressId" unique="true" class="Address"/>

</set>

</class>

<class name="Address">

<id name="id" column="addressId">

<generator class="native"/>

</id>

<join table="PersonAddress" inverse="true" optional="true">

<key column="addressId"/>

<many-to-one name="person" column="personId" not-null="true"/>

</join>

</class>

create table Person ( personId int not null primary key )

Page 38: Rapport hibernate

- 37 -

Rapport du projet de recherche : Le framework Hibernate 37

create table PersonAddress (

personId int not null,

addressId int not null primary key

)

create table Address ( addressId int not null primary key )

2.4.2. Plusieurs-à-plusieurs

Finalement nous avons l'association bidirectionnelle plusieurs-à-plusieurs. Voici un

exemple :

<class name="Person">

<id name="id" column="personId">

<generator class="native"/>

</id>

<set name="addresses" table="PersonAddress">

<key column="personId"/>

<many-to-many column="addressId" class="Address"/>

</set>

</class>

<class name="Address">

<id name="id" column="addressId">

<generator class="native"/>

</id>

<set name="people" inverse="true" table="PersonAddress">

<key column="addressId"/>

<many-to-many column="personId" class="Person"/>

</set>

</class>

create table Person ( personId int not null primary key )

create table PersonAddress (

personId int not null,

addressId int not null,

primary key (personId, addressId)

)

create table Address ( addressId int not null primary key )

3. Les entités persistées

− Une entité est un POJO qui doit être persisté.

Page 39: Rapport hibernate

- 38 -

Rapport du projet de recherche : Le framework Hibernate 38

− Implémente un constructeur sans paramètres.

− Pour la marquer un objet comme entité avec une annotation, on précède sa

déclaration par l’annotation @Entity du package @javax.persistence.Entity.

− L’annotation @Id marque une propriété comme identifiant.

− Un Id est recommandé (recommandation des nouvelles versions).

− On doit implémenter les méthodes equals() et hashCode().

* POJO : (Plain Old Java Object) Une classe Java ordinaire qui n’implémente aucune interface et

n’étends pas également aucune classe.

Page 40: Rapport hibernate

- 39 -

Rapport du projet de recherche : Le framework Hibernate 39

La configuration

Hibernate est conçu pour fonctionner dans de nombreux environnements, c'est pourquoi il

existe beaucoup de paramètres de configuration.

Il est possible de configurer Hibernate de trois manières :

− Par programmation ;

− A travers un fichier hibernate.properties ;

− Un descripteur de déploiement XML ;

1. Configuration par programmation

Une instance de org.hibernate.cfg.Configuration représente un ensemble de mappages des

classes Java d'une application vers la base de données SQL. La Configuration est utilisée

pour construire un objet (immuable) SessionFactory (Cf. Configuration – SessionFactory).

Les mappages sont constitués d'un ensemble de fichiers de mappage XML.

L’objet Configuration permet également de spécifier les propriétés de configuration. Voici

un exemple :

L’objet configuration possède plusieurs méthodes qui permettent de faire la configuration

nécessaire.

− La méthode addClass() permet d’ajouter à l’objet Configuration une classe mappées.

− La méthode setProperty() permet de spécifier les propriétés de configuration.

− Chaque méthode retourne un objet de type Configuration qui englobe les

modifications faites.

Figure 26. Exemple de configuration par programmation

IV

Page 41: Rapport hibernate

- 40 -

Rapport du projet de recherche : Le framework Hibernate 40

2. Configuration à travers le fichier hibernate.properties

On ajoute les propriétés et leurs valeurs dans ce fichier qui doit être placé à la racine du

classpath. Exemple :

3. Configuration à travers un fichier de configuration XML

Une approche alternative de la configuration est de spécifier

toute la configuration dans un fichier. Ce fichier peut

remplacer ou bien utiliser en parallèle avec le fichier

hibernate.properties.

− Le fichier de configuration et par défaut se trouve dans la racine de notre classpath. − Le fichier de configuration porte par défaut le nom hibernate.cfg.xml. − Toutefois, il est possible de le nommer différemment à condition de spécifier le fichier de configuration au moment de la création de l’objet SessionFactory

Voici un exemple d’un fichier de configuration :

Figure 27. Exemple de configuration à travers le fichier hibernate.properties

Figure 28. Emplacement du fichier de configuration XML

Figure 29. Exemple d'un fichier de configuration XML

Page 42: Rapport hibernate

- 41 -

Rapport du projet de recherche : Le framework Hibernate 41

4. Propriétés de configuration

Le tableau ci-dessous présente les différentes propriétés que nous pourrons spécifier pour

configurer Hibernate :

hibernate.connection.driver_class (Obligatoire) Classe du driver de connexion

à la base de données.

hibernate.connection.url (Obligatoire) URL de connexion à la base de

données.

hibernate.connection.username (Obligatoire) Utilisateur de la base de

données.

hibernate.connection.password (Obligatoire) Mot de passe de la base de

données.

hibernate.connection.pool_size Nombre maximum de connexions dans le

pool.

hibernate.dialect (Obligatoire) Spécifie quelle variante du

SQL Hibernate va générer.

hibernate.hbm2ddl.auto Valide ou exporte automatiquement le

schéma.

hibernate.show_sql Écrit toutes les requêtes SQL sur la console.

hibernate.format_sql Écrit le SQL dans le journal et la console.

hibernate.transaction.auto_close_session

Si activée, la session sera automatiquement

fermée pendant la phase qui suit la fin de la

transaction.

hibernate.use_identifier_rollback

Si activée, les propriétés correspondantes à

l'identifiant des objets vont être remises aux

valeurs par défaut lorsque les objets seront

supprimés.

hibernate.transaction.flush_before_com

pletion

Si activée, la session sera automatiquement

vidée durant la phase qui précède la fin de

la transaction.

Page 43: Rapport hibernate

- 42 -

Rapport du projet de recherche : Le framework Hibernate 42

› Dialectes SQL :

Ce dialecte va servir à Hibernate pour optimiser certaines parties de l'exécution en utilisant

les propriétés spécifiques à la base. Cela se révèle très utile pour la génération de clé primaire

et la gestion de concurrence.

SGBD Dialecte

DB2 org.hibernate.dialect.DB2Dialect

DB2 AS/400 org.hibernate.dialect.DB2400Dialect

DB2 OS390 org.hibernate.dialect.DB2390Dialect

PostgreSQL org.hibernate.dialect.PostgreSQLDialect

MySQL org.hibernate.dialect.MySQLDialect

MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect

MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect

Oracle org.hibernate.dialect.OracleDialect

Oracle 9i/10g org.hibernate.dialect.Oracle9Dialect

Sybase org.hibernate.dialect.SybaseDialect

Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect

Microsoft SQL Server org.hibernate.dialect.SQLServerDialect

SAP DB org.hibernate.dialect.SAPDBDialect

Informix org.hibernate.dialect.InformixDialect

HypersonicSQL org.hibernate.dialect.HSQLDialect

Ingres org.hibernate.dialect.IngresDialect

Progress org.hibernate.dialect.ProgressDialect

Mckoi SQL org.hibernate.dialect.MckoiDialect

Interbase org.hibernate.dialect.InterbaseDialect

Pointbase org.hibernate.dialect.PointbaseDialect

FrontBase org.hibernate.dialect.FrontbaseDialect

Firebird org.hibernate.dialect.FirebirdDialect

Page 44: Rapport hibernate

- 43 -

Rapport du projet de recherche : Le framework Hibernate 43

5. SessionFactory

5.1. Description

Nous récupérons la configuration de Hibernate afin d’obtenir une fabrique d’instance

session (org.hibernate.Session). Cette fabrique n’est que SessionFactory

(org.hibernate.SessionFactory).

› SessionFactory :

− C’est une fabrique d’instances session ;

− Les instances de SessionFactory sont thread-safe ;

− Ses instance sont généralement partagés à travers l’application ;

− SessionFactory est un objet lourd, il charge :

+ Les informations de la connexion à la base de données ;

+ La configuration de Hibernate ;

+ Les fichiers de mapping ;

− La création de plusieurs instances rend l’application très lourde ;

− Généralement, nous utilisons une seule instance de SessionFactory par application,

et une session par client ;

− Si une application a plusieurs sources de données, nous pouvons avoir plus d’une

SessionFactory ;

5.2. Création d’une instance SessionFactory

La création d’une SessionFactory est faite par l’intermédiaire de l’objet Configuration qui

charge la configuration :

- à partir du fichier de configuration XML, s’il existe déjà :

- L’objet configuration nous permet de créer une SessionFactory à l’aide de la méthode

buildSessionFactory() :

Page 45: Rapport hibernate

- 44 -

Rapport du projet de recherche : Le framework Hibernate 44

5.3. Méthodes de SessionFactory

Parmi les méthodes de SessionFactory les plus utilisées, nous trouvons :

− openSession() : permet d’ouvrir une nouvelle session ;

− getCurrentSession() : permet de récupérer la session courante. La définition exacte

de "current" est contrôlé par CurrentSessionContext ;

− close() : détruit la SessionFactory et libère toutes les ressources ;

5.4. Connexion à plusieurs bases de données

Pour ouvrir plusieurs connexions à différents bases de données, il faut créer autant

d’instances SessionFactory que les sources de données. Pour ce faire :

− Nous devons créer deux fichiers de configuration XML nommés différemment ;

− Chaque fichier de configuration contiendra les informations spécifiques à une base

de données ;

− Par la suite, dans notre une classe qui se charge de la création des instances

SessionFactory, nous faisons de telle manière de pouvoir récupérer l’instance

voulue ;

Page 46: Rapport hibernate

- 45 -

Rapport du projet de recherche : Le framework Hibernate 45

La persistance des objets

1. Session

Le chargement d’un objet mappé de la base de données ou la mise à jour (UPDATE,

INSERT ou DELETE) ne peut se faire que si une session Hibernate est instanciée. La

session est une couche représentée par l’interface org.hibernate.Session.

Toute activité de Hibernate commence qu’après l’ouverture d’une session à partir de la

fabrique SessionFactory.

2. Les méthodes de Session

Le tableau ci-dessous présente les différentes méthodes de Session :

save(), persist() Rendent un objet transient persistent.

load(), get() Chargent des instances depuis la base de données.

close() Ferme la session.

beginTransaction() Commence une unité de travail et retourne une Transaction.

clear() Vide le cache de la session.

contains() Vérifie si l’instance en paramètre est associée avec la session.

disconnect() Déconnecte la session de la connexion JBDC.

flush() Force la session à être synchronisée avec la base de données.

getSessionFactory() Retourne la SessionFactory qui a créé cette session.

refresh() Relit l’état de l’instance en paramètre depuis la BDD.

3. Les états des objets

Hibernate définit et prend en charge les états d'objets suivants :

− Transient - un objet est dit transient s'il a juste été instancié en utilisant l'opérateur new.

Il n'a aucune représentation persistante dans la base de données et aucune valeur

d'identifiant n'a été assignée. Ces instances seront détruites par le ramasse-miettes si

l'application n'en conserve aucune référence. Nous utilisons la Session d'Hibernate pour

V

Page 47: Rapport hibernate

- 46 -

Rapport du projet de recherche : Le framework Hibernate 46

rendre un objet persistant (et laisser Hibernate s'occuper des expressions SQL qui ont

besoin d'être exécutées pour cette transition).

− Persistant - une instance persistante a une représentation dans la base de données et une

valeur d'identifiant. Elle pourrait avoir juste été sauvegardée ou chargée, pourtant, elle

est par définition dans la portée d'une Session. Hibernate détectera tout changement

effectué sur un objet dans l'état persistant et synchronisera l'état avec la base de données

lors de la fin de l'unité de travail. Les développeurs n'exécutent pas d'expressions

UPDATE ou DELETE manuelles lorsqu'un objet devrait être rendu éphémère.

− Detached - une instance détachée est un objet qui a été persistant, mais dont la Session

a été fermée. La référence à l'objet est encore valide, bien sûr, et l'instance détachée

pourrait même être modifiée dans cet état. Une instance détachée peut être rattachée à

une nouvelle Session ultérieurement, la rendant (et toutes les modifications avec) de

nouveau persistante. Cette fonctionnalité rend possible un modèle de programmation

pour de longues unités de travail qui requièrent un temps de réflexion de l'utilisateur.

Nous les appelons des conversations, c'est-à-dire une unité de travail du point de vue de

l'utilisateur.

Figure 30. Changement des états d'objet en fonction des méthodes

Page 48: Rapport hibernate

- 47 -

Rapport du projet de recherche : Le framework Hibernate 47

4. Chargement des objets

− Les méthodes load() de Session donnent un moyen de récupérer une instance persistante

si vous connaissez déjà son identifiant. load() prend un objet de classe et chargera l'état

dans une instance nouvellement instanciée de cette classe, dans un état persistant.

− Si vous n'êtes pas certain qu'une ligne correspondante existe, vous utiliserez la méthode

get(), laquelle accède à la base de données immédiatement et retourne null s'il n'y a pas

de ligne correspondante.

5. Rendre des objets persistants

Les objets, d’une classe persistante, nouvellement instanciés sont considérés par Hibernate

« transient ». Pour rendre un objet persistant, nous devons l’associer à une session en faisant

appel à une des trois méthodes :

− save() : garantit le retour d'un identifiant. Si une instruction INSERT doit être exécutée

pour obtenir l'identifiant (par exemple, le générateur "identity", et non pas "sequence"),

cet INSERT se produit immédiatement, que vous soyez à l'intérieur ou à l'extérieur d'une

transaction. C'est problématique dans une conversation longue dans un contexte de

session/persistance étendu.

− persist() : rend une instance transient persistante. Toutefois, il ne garantit pas que la

valeur d'identificateur soit affectée à l'instance permanente immédiatement, l'affectation

peut se produire au moment de flush. persist() garantit également qu'il ne s'exécutera

pas un énoncé INSERT s'il est appelée en dehors des limites de transaction. C'est utile

pour les longues conversations dans un contexte de session/persistance étendu.

− saveOrUpdate() : cette méthode implémente la fonctionnalité de pouvoir détecter

automatiquement l’état d’un objet, et effectuer par la suite l’opération adéquate :

+ save() si l’objet est encore transient ;

+ mettre à jour l’objet s’il existe déjà ;

Figure 32. Exemple de la méthode save()

Figure 31. Exemple de la méthode load()

Page 49: Rapport hibernate

- 48 -

Rapport du projet de recherche : Le framework Hibernate 48

6. Détacher des objets persistants

evict() permet de détacher un objet de la session, ce qui permettra de le modifier sans que

les nouveaux changements soient reportés sur la base de données.

7. Mise à jour des données

La mise à jour de données correspondantes aux objets modifiés se fait généralement

automatiquement si les objets sont chargés dans la session. Sinon, cela peut être fait en

utilisant une des méthodes suivantes :

− saveOrUpdate() : comme mentionné ci-dessus, cette méthode a double fonction :

+ rattacher un objet à une session et l’enregistrer par la suite dans la base

données ;

+ mettre à jour un objet s’il existe déjà ;

− update() : méthode dont sa fonction unique est d’effectuer la mise à jour d’un objet passé

en paramètre ;

− flush() : l’appel de cette méthode engendra la synchronisation l’état de la connexion

JDBC avec l'état des objets retenus en mémoire ;

8. Suppression d'objets persistants

delete() supprimera l'état d'un objet de la base de données. Bien sûr, l’application pourrait

encore conserver une référence vers un objet effacé. Il est préférable de penser à delete()

comme rendant une instance persistante éphémère (transient).

Il est possible d’effacer des objets dans n’importe quel ordre, sans risque de violations de

contrainte de clef étrangère. Il est encore possible de violer une contrainte NOT NULL sur

une colonne de clef étrangère en effaçant des objets dans le mauvais ordre, par exemple si

vous effacez le parent, mais oubliez d'effacer les enfants.

9. Flush de la session

De temps en temps la Session exécutera les expressions SQL requises pour synchroniser

l'état de la connexion JDBC avec l'état des objets retenus en mémoire. Ce processus, flush,

survient par défaut aux points suivants :

− avant certaines exécutions de requête ;

− lors d'un appel à org.hibernate.Transaction.commit() ;

− lors d'un appel à Session.flush() ;

Page 50: Rapport hibernate

- 49 -

Rapport du projet de recherche : Le framework Hibernate 49

Les expressions SQL sont effectuées dans l'ordre suivant :

− insertion des entités, dans le même ordre que celui des objets correspondants

sauvegardés par l'appel à Session.save() ;

− mise à jour des entités ;

− suppression des collections ;

− suppression, mise à jour et insertion des éléments des collections ;

− insertion des collections ;

− suppression des entités, dans le même ordre que celui des objets correspondants

qui ont été supprimés par l'appel de Session.delete() ;

10. Les transactions

Une transaction est un objet qui définit une unité de travail atomique. Une transaction

encapsule différentes opérations. Nous démarrons une transaction par la session et pour

valider les changements intervenus durant cette transaction, il faut procéder à un commit

de celle-ci.

Une transaction est un regroupement d’opérations sur une base de données effectuant un

traitement fonctionnel atomique. C.-à-d. si une opération échoue, toute la transaction sera

annulée.

› L’interface Transaction

Une transaction est associée à une session. Elle est instanciée à travers l’appel

session.beginTransaction() ;

Voici les méthodes de Transaction :

− void begin() : débute une nouvelle transaction ;

− void commit() : pour appliquer les opérations effectuées sur la base de données, et

finir par conséquent la transaction ;

Figure 33. Cycle de vie d'une transaction

Page 51: Rapport hibernate

- 50 -

Rapport du projet de recherche : Le framework Hibernate 50

− void rollback() : force la transaction d’annuler toute les opérations ;

− void setTimeout(int seconds) : définit un temps mort pour la transaction ;

− boolean isAlive() : vérifie si la transaction est encore active ;

− boolean wasCommited() : vérifie si la transaction est effectuée avec succès ;

− boolean wasRolledBack() : vérifie si la transaction est annulée avec succès ;

› Exemple d’une transaction

Session session = null;

Transaction tx = null;

try {

session = sessionFactory.openSession();

tx = session.beginTransaction();

//opérations à effectuer

tx.commit();

}

catch(Exception e) {

tx.rollback();

}

finally {

session.close();

}

Il est préférable d’annuler la transaction si une exception se déclenche afin de libérer les

ressources.

Page 52: Rapport hibernate

- 51 -

Rapport du projet de recherche : Le framework Hibernate 51

Requêtage avec Hibernate

1. Hibernate Query Language

HQL est un langage de requête orienté objet, similaire à SQL, mais au lieu d’opérer sur les

tables et les colonnes, HQL utilise les classes persistantes et leurs propriétés.

Les requêtes HQL sont traduites par Hibernate à des requêtes SQL, qui s’appliquent par la

suite sur la base de données.

Il est recommandé d’utiliser HQL au lieu de SQL native pour éviter les problèmes de

portabilité au niveau de la base de données et aussi pour profiter des stratégies de cache et

de génération de Hibernate.

› La clause FROM

Elle est utilisée pour charger tous les objets de la classe spécifiée dans la mémoire.

String hql = "FROM Employee";

Query query = session.createQuery(hql);

List results = query.list();

› La clause SELECT

Elle permet d’obtenir propriétés des objets au lieu de toutes leurs propriétés.

String hql = "SELECT E.firstName FROM Employee E";

Query query = session.createQuery(hql);

List results = query.list();

› La clause WHERE

Pour réduire le nombre de résultats retourné en spécifiant une ou plusieurs conditions.

String hql = "FROM Employee E WHERE E.id = 10";

Query query = session.createQuery(hql);

List results = query.list();

VI

Page 53: Rapport hibernate

- 52 -

Rapport du projet de recherche : Le framework Hibernate 52

› La clause ORDER BY

Pour trier le résultat de la requête. La clause ORDER BY est suivie des mots clés ASC ou

DESC, qui précisent respectivement si le tri se fait de manière croissante ou décroissante.

String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";

Query query = session.createQuery(hql);

List results = query.list();

› La clause GROUP BY

Pour regrouper le résultat sur la base d’une ou plusieurs propriétés.

String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E " +

"GROUP BY E.firstName";

Query query = session.createQuery(hql);

List results = query.list();

› Named Parameters

Pour définir un paramètre dans une requête HQL. Ceci permet d’éviter les hacks de type

SQL injection.

String hql = "FROM Employee E WHERE E.id = :employee_id";

Query query = session.createQuery(hql);

query.setParameter("employee_id",10);

List results = query.list();

› La clause INSERT

HQL supporte la clause INSERT INTO seulement si un objet est créé à partir d’un autre

objet.

String hql = "INSERT INTO Employee(firstName, lastName, salary)" +

"SELECT firstName, lastName, salary FROM old_employee";

Query query = session.createQuery(hql);

int result = query.executeUpdate();

System.out.println("Rows affected: " + result);

Page 54: Rapport hibernate

- 53 -

Rapport du projet de recherche : Le framework Hibernate 53

› La clause UPDATE

Pour mettre à jour les propriétés d’un ou plusieurs objets.

String hql = "UPDATE Employee set salary = :salary " + "WHERE id = :employee_id";

Query query = session.createQuery(hql);

query.setParameter("salary", 1000);

query.setParameter("employee_id", 10);

int result = query.executeUpdate();

System.out.println("Rows affected: " + result);

› La clause DELETE

Pour supprimer un ou plusieurs objets.

String hql = "DELETE FROM Employee " + "WHERE id = :employee_id";

Query query = session.createQuery(hql);

query.setParameter("employee_id", 10);

int result = query.executeUpdate();

System.out.println("Rows affected: " + result);

› Les fonctions d’agrégat

HQL supporte toutes les fonctions d’agrégat de SQL.

String hql = "SELECT count(distinct E.firstName) FROM Employee E";

Query query = session.createQuery(hql);

List results = query.list();

2. L’API Criteria

En plus de HQL pour réaliser des requêtes d'extraction de données, Hibernate propose une

API qui permet de construire des requêtes pour interroger la base de données. Criteria

propose donc une alternative à HQL sous la forme d'une API.

L'API Criteria propose d'avoir une approche orientée objet pour définir des requêtes et

obtenir des données. L'utilisation de cette API permet d'avoir un meilleur contrôle grâce à

la compilation.

Cette API permet facilement de combiner de nombreux critères optionnels pour créer une

requête : elle est particulièrement adaptée pour créer dynamiquement des requêtes à la

volée comme c'est le cas par exemple pour des requêtes effectuant des recherches

multicritères à partir d'informations fournies par l'utilisateur.

Page 55: Rapport hibernate

- 54 -

Rapport du projet de recherche : Le framework Hibernate 54

Elle propose des classes et des interfaces qui encapsulent les fonctionnalités de SQL dont les

principales sont :

− Criteria

− Criterion

− Restrictions

− Projection

− Order

2.1. L'interface org.hibernate.criterion.Criteria

L’interface Criteria est le point d'entrée pour utiliser l'API Criteria. Elle permet de définir

une requête à partir de critères pour retrouver des données.

› Comment obtenir ?

Une instance de l'interface Criteria est obtenue en invoquant la méthode createCriteria() de

la session hibernate. Elle reçoit en paramètre la classe d'une entité sur laquelle les critères

vont s'appliquer.

› Ses méthodes :

L’exemple ci-dessous, permet de récupérer tous les objets Produit :

2.2. L'interface org.hibernate.criterion.criterion

Le type Criterion encapsule un élément de la clause WHERE de la requête SQL qui sera

générée. Il permet de définir un critère à appliquer à la requête.

add(Criterion criterion) ajouter un critère Criteria.

addOrder(Order order) Ajouter un ordre de trie.

list() obtenir les résultats de la requête. setProjection(Projection projection) préciser le contenu du résultat de la requête.

Figure 34. Exemple de Criteria

Page 56: Rapport hibernate

- 55 -

Rapport du projet de recherche : Le framework Hibernate 55

› Comment obtenir ?

− Chaque instance d'un critère doit être ajoutée aux critères de la requête en utilisant la

méthode add() de l'instance de type Criteria.

− L'API propose plusieurs fabriques qui permettent d'instancier les différents objets qui

vont définir le contenu de la requête.

− La classe org.hibernate.criterion.Restrictions est une fabrique qui propose des méthodes

pour obtenir différentes instances de Criterion.

2.3. La classe org.hibernate.criterion.Restrictions

La classe org.hibernate.criterion.Restrictions est une fabrique qui permet de créer des

critères de recherche sous la forme d'instances de type Criterion. Les critères proposés

encapsulent les opérateurs SQL standards.

Elle propose des méthodes statiques pour créer des instances des différentes

implémentations de l'interface Criterion proposées par Hibernate.

› Ses méthodes :

and(Criterion lhs, Criterion rhs) Créer un critère de type "and" qui est vrai si les deux critères sont évalués à vrai

between(String propertyName, Object lo, Object hi)

Permet d'appliquer une contrainte SQL de type "between" : la valeur de la propriété dont le nom est fourni en paramètre doit être comprise entre les deux valeurs fournies

eq(String propertyName, Object value)

Permet d'appliquer une contrainte SQL de type égalité : la valeur de la propriété doit être égale à la valeur fournie en paramètre

ge(String propertyName, Object value)

Permet d'appliquer une contrainte SQL de type "supérieur ou égal" : la valeur de la propriété doit être supérieure ou égale à la valeur fournie en paramètre

gt(String propertyName, Object value)

Permet d'appliquer une contrainte SQL de type "supérieur à" : la valeur de la propriété doit être supérieure à la valeur fournie en paramètre

in(String property, Collection values)

La valeur de la propriété dont le nom est fourni en paramètre doit être égale à l'une de celles fournies dans la collection

isEmpty(String property) Le contenu de la collection de la propriété dont le nom est fourni en paramètre ne doit pas avoir d'éléments

isNotEmpty(String property) Le contenu de la collection de la propriété dont le nom est fourni en paramètre doit avoir au moins un élément

isNotNull(String propertyName) Permet d'appliquer une contrainte SQL de type "is not null" : la valeur de la propriété dont le nom est fourni en paramètre doit être non null

isNull(String propertyName) Permet d'appliquer une contrainte SQL de type "is null" : la valeur de la propriété dont le nom est fourni en paramètre doit être null

le(String property, Object value) La valeur de la propriété dont le nom est fourni en paramètre doit être inférieure ou égale à la valeur fournie

like(String property, Object value) La valeur de la propriété dont le nom est fourni en paramètre doit respecter le motif de l'opérateur SQL like fourni en paramètre

lt(String property, Object value) La valeur de la propriété doit être inférieure à la valeur fournie en paramètre

ne(String propertyName, Object value)

Permet d'appliquer une contrainte SQL de type "est différent de" : la valeur de la propriété dont le nom est fourni en paramètre doit être différente de la valeur fournie

not(Criterion expression) L'évaluation du critère fourni en paramètre doit être false

or(Criterion lhs, Criterion rhs) L'évaluation d'un des deux critères fourni en paramètre doit être true

Page 57: Rapport hibernate

- 56 -

Rapport du projet de recherche : Le framework Hibernate 56

− Les opérateurs de comparaison sont encapsulés dans des méthodes de la classe

Restrictions : eq(), lt(), le(), gt(), ge().

List<Personne> personnes = session.createCriteria(Personne.class)

.add(Restrictions.lt("dateNais", dateSaisie))

.list();

− La classe Restrictions propose aussi des méthodes pour les opérateurs SQL : like,

between, in, is null, is not null...

List<Personne> personnes = session.createCriteria(Personne.class)

.add(Restrictions.between("dateNais", dateDeb, dateFin))

.add(Restrictions.like("nom", "Dup%"))

.list();

− Il est possible d'utiliser les méthodes or() et and() pour réaliser des combinaisons de

critères.

List<Personne> personnes = session.createCriteria(Personne.class)

.add(Restrictions.or(Restrictions.eq("prenom", "Jean"),

Restrictions.eq("prenom", "Paul")))

.list();

2.4. La classe org.hibernate.criterion.Projection

La classe org.hibernate.criterion.Projection permet de préciser un champ qui sera retourné

dans le résultat de la requête : ce champ peut être issu d'une table, du calcul d'une

agrégation, de la définition d'un alias...etc.

› Comment obtenir ?

Pour ajouter un champ, il faut passer le nom du champ en paramètre de la méthode statique

property() de la classe Projection. L'instance retournée est passée en paramètre de la

méthode setProjection().

− La classe org.hibernate.criterion.Projections est une fabrique pour créer des instances

de type Projection.

− Pour préciser plusieurs champs, il faut utiliser la méthode propertyList() de la classe

ProjectionList.

List resultats = session.createCriteria(Personne.class)

.setProjection(Projections.projectionList()

.add(Projections.property("nom"))

.add(Projections.property("prenom")

.list();

Page 58: Rapport hibernate

- 57 -

Rapport du projet de recherche : Le framework Hibernate 57

3. SQL natif

En plus de HQL et Criteria, Hibernate nous permet d’écrire nos requêtes dans le dialecte

SQL natif pour toutes les opérations de création de mise à jour, suppression et chargement.

Ceci est utile si nous voulons profiter des fonctionnalités spécifiques de la base de données,

ce qui nécessite un accès direct au SQL natif.

Pour exécuter les requêtes en SQL natif, nous devons disposer d’abord d’un objet de type

SQLQuery, qui est une interface permettant de contrôler l’exécution des requêtes.

3.1. Requêtes scalaires

Pour récupérer un objet de type SQLQuery, il faut appeler la méthode createSqlQuery() de

la Session que nous lui communiquons notre requête sous format String.

› Exemple :

Par défaut, cette instruction retournera toujours un tableau d’objets (Object[]) avec les

valeurs scalaires de chacune des colonnes de la table « produit ».

3.2. Requêtes d’entités

Pour ne pas récupérer des valeurs scalaires brutes, et pour avoir des entités depuis une

requête SQL natif, nous utilisons la méthode de l’interface SqlQuery addEntity() qui reçoit

comme paramètre un objet de type Class de l’entité persistante que nous voulons récupérer.

› Exemple :

Pour exécuter une requête de sélection, nous utilisons la méthode list() de SqlQuery.

3.3. Requêtes de mise à jour des données

Pour exécuter les requêtes de mise à jour de données, nous utilisons la méthode

executeUpdate() de l’interface SqlQuery.

Figure 35. Exemple de requête scalaire

Figure 36. Exemple de requête d'entité

Page 59: Rapport hibernate

- 58 -

Rapport du projet de recherche : Le framework Hibernate 58

› Exemples :

- Requête Delete :

- Requête Update :

- Requête d’insertion

3.4. Gestion des associations et des collections

Pour charger les collections ou les associations, et pour éviter un aller-retour supplémentaire

vers la base de données à chaque fois que nous voulons retourner un objet contenant une

collection ou association, nous appelons à la méthode addJoin() de l’interface SqlQuery qui

nous permet de joindre des entités dans notre résultat retourné.

› Exemple :

Dans cet exemple, les produits retournés auront leur propriété catégorie entièrement

initialisée sans aucun aller-retour supplémentaire vers la base de données.

La méthode addJoin() reçoit comme paramètre un alias « produit », pour être capable de

spécifier le chemin de la propriété cible de la jointure dans le deuxième paramètre, dans cet

exemple, c’est la propriété « cat » dans la classe Produit que nous voulons joindre .

La même chose pour une collection, par exemple si nous voulons joindre à notre résultat

retourné des catégories la collection des produits qui l’appartiennent :

Figure 37. Exemple de requête Delete

Figure 38. Exemple de requête Update

Figure 39. Exemple de requête d'insertion

Page 60: Rapport hibernate

- 59 -

Rapport du projet de recherche : Le framework Hibernate 59

Dans cet exemple, la propriété que nous voulons joindre est la liste des produits nommé

listProduits dans la classe Catégorie.

3.5. Les paramètres

Il est risqué de construire une requête à partir d’une chaîne de caractères dont une partie est

constituée de chaînes saisies par un utilisateur, Il faut plutôt utiliser les possibilités de

paramétrage offertes par Hibernate.

L'interface d'interrogation SqlQuery supporte l'utilisation des paramètres nommés et les

paramètres de positions. Les paramètres nommés sont des variables de la forme :name que

l'on peut retrouver dans la requête.

SqlQuery dispose de méthodes pour lier des valeurs à ces paramètres nommés et aux

paramètres de positions selon leurs types.

Les paramètres de positions sont plus sensibles aux modifications (si on ajoute un paramètre

par exemple), donc c’est mieux d’utiliser les paramètres nommés dont les avantages sont :

- Les paramètres nommés sont indépendants de l'ordre dans lequel ils apparaissent

dans la requête ;

- Ils peuvent être présents plusieurs fois dans une même requête ;

- Ils sont auto-documentés (par leur nom) ;

› Exemples :

- Paramètre de position :

- Paramètre nommé :

Figure 40. Exemple de paramètre de position

Figure 41. Exemple de paramètre nommé

Page 61: Rapport hibernate

- 60 -

Rapport du projet de recherche : Le framework Hibernate 60

Hibernate Validator

1. Principe

La validation des données est une tâche commune entre toutes les couches d’une

application. Généralement, la même logique de validation est appliquée au niveau des

différentes couches, chose qui prend beaucoup de temps et qui peut contenir des erreurs.

Pour éviter la duplication du processus de la validation sur l’ensemble des couches,

Hibernate Validator permet d’exprimer les contraintes seulement au niveau des modèles de

données, et faire la validation au niveau des différentes couches. Ces contraintes sont

exprimées par les annotations.

Pour cela, Hibernate Validator implémente les deux spécifications JAVA (JSR303, JSR349)

concernant la validation des beans.

Figure 42. Principe de la validation classique

Figure 43. Principe de la validation par Hibernate Validator

VII

Page 62: Rapport hibernate

- 61 -

Rapport du projet de recherche : Le framework Hibernate 61

2. Description de Hibernate Validator

Les annotations sont une manière très commode et élégante pour spécifier des contraintes

invariantes sur un modèle de données. Vous pouvez, par exemple, indiquer qu'une

propriété ne devrait pas être nulle, que le solde d'un compte devrait être strictement positif,

etc. Ces contraintes de modèle de données sont déclarées dans le bean lui-même en annotant

ses propriétés. Un validateur peut alors les lire et vérifier les violations de contraintes. Le

mécanisme de validation peut être exécuté dans différentes couches de votre application

(présentation, accès aux données) sans devoir dupliquer ces règles. Hibernate Validator a

été conçu dans ce but.

Hibernate Validator fonctionne sur deux niveaux. D'abord, il est capable de vérifier des

violations de contraintes sur les instances d'une classe en mémoire. Ensuite, il peut

appliquer les contraintes au méta-modèle d'Hibernate et les incorporer au schéma de base

de données généré.

Chaque annotation de contrainte est associée à l'implémentation du validateur responsable

de vérifier la contrainte sur l'instance de l'entité. Un validateur peut aussi (optionnellement)

appliquer la contrainte au méta-modèle d'Hibernate, permettant à Hibernate de générer le

DDL qui exprime la contrainte. Avec le listener d'événements approprié, vous pouvez

exécuter l'opération de vérification lors des insertions et des mises à jour effectuées par

Hibernate. Hibernate Validator n'est pas limité à Hibernate. Vous pouvez facilement

l'utiliser n'importe où dans votre application.

Lors de la vérification des instances à l'exécution, Hibernate Validator retourne des

informations à propos des violations de contraintes dans un tableau de InvalidValues.

Parmi d'autres informations, InvalidValue contient un message de description d'erreur qui

peut inclure les valeurs des paramètres associés à l'annotation (p. ex. la limite de taille), et

des chaînes de caractères qui peuvent être externalisées avec un ResourceBundle.

3. Les contraintes intégrées

Hibernate Validator arrive avec des contraintes intégrées, lesquelles couvrent la plupart

des vérifications de données de base. Comme nous le verrons plus tard, nous ne sommes

pas limités à celles-ci, nous pouvons écrire nos propres contraintes.

Annotation S'applique à Vérification à l'exécution Impact sur

les méta-

données

@Length(min, max) propriété

(String)

vérifie si la longueur de la chaîne de

caractères est comprise dans

l'intervalle

la longueur

de la

colonne sera

positionnée

à max

@Max(value) propriété

(nombre ou

vérifie si la valeur est inférieure ou

égale à max

ajoute une

contrainte

Page 63: Rapport hibernate

- 62 -

Rapport du projet de recherche : Le framework Hibernate 62

chaîne de

caractères

représentant un

nombre)

de

vérification

sur la

colonne

@Min(value) propriété

(nombre ou

chaîne de

caractères

représentant un

nombre)

vérifie si la valeur est supérieure ou

égale à max

ajoute une

contrainte

de

vérification

sur la

colonne

@NotNull propriété vérifie si la valeur n'est pas nulle les colonnes

sont

marquées

"not null"

@Past propriété (Date

ou Calendar)

vérifie si la date est dans le passé ajoute une

contrainte

de

vérification

sur la

colonne

@Future propriété (Date

ou Calendar)

vérifie si la date est dans le futur aucun

@Pattern(regex, flag) propriété

(String)

vérifie si la propriété correspond à

l'expression rationnelle donnée (pour

"flag", voir

java.util.regex.Pattern)

aucun

@Range(min, max) propriété

(nombre ou

chaîne de

caractères

représentant un

nombre)

vérifie si la valeur est comprise entre

min et max (inclus)

ajoute une

contrainte

de

vérification

sur la

colonne

@Size(min, max) propriété

(tableau,

collection, map)

vérifie si la taille de l'élément est

comprise entre min et max (inclus)

aucun

@AssertFalse propriété vérifie que la méthode est évaluée à

faux (utile pour les contraintes

exprimées dans le code plutôt que

dans les annotations)

aucun

@AssertTrue propriété vérifie que la méthode est évaluée à

vrai (utile pour les contraintes

exprimées dans le code plutôt que

dans les annotations)

aucun

@Valid propriété (objet) exécute la validation récursivement

sur l'objet associé. Si l'objet est une

Collection ou un tableau, les

éléments sont validés récursivement.

Si l'objet est une Map, les éléments

valeur sont validés récursivement.

aucun

Page 64: Rapport hibernate

- 63 -

Rapport du projet de recherche : Le framework Hibernate 63

@Email propriété

(String)

vérifie si la chaîne de caractères est

conforme à la spécification d'une

adresse e-mail

aucun

4. Déclaration et validation des contraintes

Dans un modèle de données, nous pouvons appliquer les contraintes au niveau des

propriétés, des méthodes et au niveau de la classe en utilisant les annotations.

La déclaration des contraintes peut être faite également par un fichier de contraintes XML,

mais il nécessite une configuration préalable.

Voici un exemple :

− Nous spécifions les contraintes par annotations, et optionnellement, nous fournissons

des paramètres supplémentaires, tel que le message à afficher en cas de violation d’une

contrainte.

Figure 44. Modèle Client annotés pour faire la validation

Page 65: Rapport hibernate

- 64 -

Rapport du projet de recherche : Le framework Hibernate 64

− Nous créons par la suite un objet qui enfreint les contraintes du Id qui doit être supérieur

à 50, et l’Email qui doit respecter la forme d’une adresse Email ordinaire :

5. Créer des contraintes personnalisées

Nous pouvons créer des contraintes en suivant trois étapes :

− Créer une annotation de contrainte ;

− Implémenter un validateur ;

− Définir un message d’erreur par défaut ;

5.1. L’annotation de contrainte

La spécification de « Bean Validation API » implique que l’annotation doit définir trois

attributs :

› Un attribut message contenant un message qui sera affiché si la contrainte est violée.

› Un attribut groups qui permet la validation de groupes.

› Un attribut payload utilisé par les clients pour assigner des objets Payload

personnalisés à une contrainte.

Exemple :

Figure 45. Exemple de la mise en œuvre de la validation

Figure 46. Exemple d'une contrainte personnalisée

Page 66: Rapport hibernate

- 65 -

Rapport du projet de recherche : Le framework Hibernate 65

5.2. Le validateur de contrainte

Nous devons implémenter l’interface ConstraintValidator :

L’interface ConstraintValidator définit deux types paramétrés. Le premier est le type de

l’annotation à valider, la deuxième est le type auquel elle s’applique.

Si une annotation doit s’appliquer à plusieurs types, un ConstraintValidator est requis

pour chaque type.

› Le ConstraintValidatorContext

En utilisant le ConstraintValidatorContext passé en paramètre, il est possible d’ajouter

d’autres messages d’erreurs ou bien désactiver les messages par défaut.

Exemple :

Figure 48. Exemple d'utilisation de ConstraintValidatorContext

Figure 47. Exemple d’implémentation d'un validateur de contrainte

Page 67: Rapport hibernate

- 66 -

Rapport du projet de recherche : Le framework Hibernate 66

6. La composition des contraintes

Parfois un élément peut être annoté par plusieurs contraintes, il est possible de le grouper

dans une seule annotation.

Pour ce faire, nous devons créer une annotation (l’annotation composée) et l’annoter avec

toutes les annotations que nous voulons appliquer sur un élément.

La collection de ConstraintViolations retirée après la validation d’une instance contiendra

une entrée pour chaque contrainte (composante) violée.

Exemple :

Figure 49. Exemple de composition des contraintes

Page 68: Rapport hibernate

- 67 -

Rapport du projet de recherche : Le framework Hibernate 67

Conclusion générale

Ce travail a comme objectif de faire une étude détaillée et une recherche sur l’un des

frameworks Java EE, qui est un framework open source nommé Hibernate, se basant sur la

persistance des objets en base de données. Hibernate apporte une solution aux problèmes

d'adaptation entre le paradigme objet et les SGBD en remplaçant les accès à la base de

données par des appels à des méthodes objet de haut niveau. Ce qui permet de concentrer

les efforts sur le métier de l’application.

L’objectif de ce projet était de bien étudier le framework Hibernate, en s'attaquant à ses

différents points, y compris : présentation du framework Hibernate et de son architecture,

la configuration, ses différents modules. La réalisation des exemples détaillés donnent une

idée sur l'utilisation de chaque module et illustrent de plus en plus l’utilité du framework

Hibernate.

Le livrable fourni, sera utile a une personne pour débuter le framework Hibernate, est un

dossier bien structuré, composé de plusieurs éléments : un manuel explicatif, des exemples

explicatifs, les fichiers nécessaires pour préparer l'environnement Hibernate et le mettre en

œuvre.

En perspectives pour ce travail, notre équipe compte enrichir nos exemples avec d’autres

plus détaillés, étudier d’autres modules composant la famille Hibernate. En se basant sur

les recherches menées par les autres groupes sur les autres frameworks, nous comptons

aussi travailler sur l’intégration de ces différents frameworks avec Hibernate.

Page 69: Rapport hibernate

- 68 -

Rapport du projet de recherche : Le framework Hibernate 68

Références

[1] Documentation officiel de Hibernate ORM.

[2] Hibernate in Action, Christian Bauer et Gavin King.

[3] JBoss Community Documentation, Hibernate - Relational Persistence for Idiomatic Java.

[4] Java Persistance et Hibernate, Anthony Patricio avec la contribution d’Olivier Salvatori.

[5] Guide to Java Persistence and Hibernate, Sebastian Hennebrueder.

[6] HIBERNATE TUTORIAL, Simply Easy Learning by tutorialspoint.com.

[7] JSR 349 Reference Implementation, Reference Guide, by Hardy Ferentschik and Gunnar

Morling.

[8] Pro Hibernate 3, Dave Minter et Jeff Linwood.