Vous êtes sur la page 1sur 90

Mapping Objet Relationnel

avec Hibernate
M.Youssfi
Introduction
:User
idUser=1
login=root
pass=root
email=
ville=
:User
idUser=2
login=toto
pass=toto
email=
ville=
:User
idUser=3
login=you
pass=you
email=
ville=
Users:Collection
Base de donnes relationnelle
Application
oriente objet
Introduction
Travailler dans les deux univers que sont
l'orient objet et la base de donnes
relationnelle peut tre lourd et
consommateur en temps dans le monde de
l'entreprise d'aujourd'hui.
Hibernate est un outil de mapping
objet/relationnel pour le monde Java.
Le terme mapping objet/relationnel (ORM)
dcrit la technique consistant faire le lien
entre la reprsentation objet des donnes
et sa reprsentation relationnelle base sur
un schma SQL.
Introduction
Hibernate s'occupe du transfert des objets
Java dans les tables de la base de donnes
En plus, il permet de requter les donnes
et propose des moyens de les rcuprer.
Il peut donc rduire de manire
significative le temps de dveloppement qui
aurait t autrement perdu dans une
manipulation manuelle des donnes via
SQL et JDBC
But de Hibernate
Le but d'Hibernate est de librer le dveloppeur de
95 pourcent des tches de programmation lies la
persistance des donnes communes.
Hibernate assure la portabilit de votre application si
vous changer de SGBD.
Hibernate n'est probablement pas la meilleure
solution pour les applications centres sur les
donnes qui n'utilisent que les procdures stockes
pour implmenter la logique mtier dans la base de
donnes,
Il est le plus utile dans les modles mtier orients
objets dont la logique mtier est implmente dans la
couche Java dite intermdiaire.
Hibernate propose au dveloppeur des mthodes
daccs aux bases de donnes plus efficace ce qui
devrait rassurer les dveloppeurs.
Premire approche de larchitecture
dHibernate
Hibernate permet dassurer la
persistance des objets de
lapplication dans un entrept
de donnes.
Cet entrept de donnes est
dans la majorit des cas une
base de donnes relationnelle,
mais il peut tre un fichier
XML.
Le mapping des objets est
effectue par Hibernate en se
basant sur des fichiers de
configuration en format texte
ou souvent XML.

Premire Application
Prparer le projet:
Au premier lieu,
nous avons besoin
de tlcharger
Hibernate et de
copier des bichiers
.jar dans le rperoire
lib de votre projet:
Pour travailler avec
une base de
donnes MySQL,
nous aurons besoin
galement du
connecteur JDBC de
MySQL

Hibernate
Pilote JDBC MySQL
Exemple dapplication
Supposant que nous avons
besoin de grer la
participation des personnes
des runions.
Une personne participe
plusieurs runions et chaque
runion concerne plusieurs
personnes.
On va sintresser tout
dabord au cas dune classe et
par la suite nous reviendrons
sur le mapping des
associations entre les classes.
Classe Reunion
package gest;
import java.util.Date;
public class Reunion {
private Long idReunion;
private Date dateReunion;
private String titreReunion;

public Reunion(){}
public Date getDateReunion() {
return dateReunion;
}
public void setDateReunion(Date
dateReunion) {
this.dateReunion =
dateReunion;
}
public Long getIdReunion() {
return idReunion;
}
public void setIdReunion(Long
idReunion) {
this.idReunion = idReunion;
}
public String getTitreReunion() {
return titreReunion;
}
public void setTitreReunion(String
titreReunion) {
this.titreReunion = titreReunion;
}
}
Fichier de mapping de la classe Reunion
La structure basique dun fichier de mapping
ressemble cel:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-
//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-
3.0.dtd">
<hibernate-mapping>
[Contenu]
</hibernate-mapping>
Contenu du fichier de mapping de la
classe Reunion: Reunion.hbm.xml
<hibernate-mapping>
<class name="gest.Reunion" table="REUNIONS">
<id name="idReunion" column="ID_REUNION">
<generator class="increment"/>
</id>
<property name="dateReunion" type="timestamp"
column="DATE_REUNION"/>
<property name="titreReunion"/>
</class>
</hibernate-mapping>
Nom et emplacement du fichier de
mapping de la classe Reunion
Pour respecter les rgles de nommage, le
fichier est nomm : Reunion.hbm.xml
Il devrait tre plac au mme endroit de la
classe Reunion:
+lib
<Hibernate et bibliothques tierces>
+src
+gest
Reunion.java
Reunion.hbm.xml
Configurer Hibernate
Nous avons maintenant une classe
persistante et son fichier de mapping. Il est
temps de configurer Hibernate.
Avant a, nous avons besoin d'une base de
donnes.
Lancer MySQL et crer une base de
donnes Nomme GEST_REUNIONS .
La structure de cette base de donnes sera
cre automatiquement par Hibernate lors
de lexcution de lapplication
Configurer Hibernate
Hibernate est la couche de votre application qui se
connecte cette base de donnes,
donc il a besoin des informations de connexion.
Les connexions sont tablies travers un pool de
connexions JDBC, que nous devons aussi configurer.
Pour la configuration d'Hibernate, nous pouvons
utiliser
un simple fichier hibernate.properties,
un fichier hibernate.cfg.xml
ou mme une configuration complte par
programmation.
La plupart des utilisateurs prfrent le fichier de
configuration XML
Configurer Hibernate : Hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-
//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-
3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/GEST_REUNIONS
</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
Configurer Hibernate : Hibernate.cfg.xml (Suite)
<property name="connection.pool_size">1</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="current_session_context_class">
thread
</property>
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping resource="gest/Reunion.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Emplacement du fichier Hibernate.cfg.xml
Ce fichier doit tre plac dans la
racine du classpath.
Cest--dire dans le rpertoire src
+lib
<Hibernate et bibliothques tierces>
+src
Hibernate.cfg.xml
+gest
Reunion.java
Reunion.hbm.xml
Application Test
Il est temps de charger et de stocker quelques objets
Reunion, mais d'abord nous devons complter la
configuration avec du code d'infrastructure.
Nous devons dmarrer Hibernate. Ce dmarrage
inclut la construction d'un objet SessionFactory global
et le stocker quelque part facile d'accs dans le code
de l'application.
Une SessionFactory peut ouvrir des nouvelles
Sessions.
Une Session reprsente une unit de travail la
SessionFactory est un objet global instanci une seule
fois.
Nous crerons une classe d'aide HibernateUtil qui
s'occupe du dmarrage et rend la gestion des Sessions
plus facile. Voici son implmentation :
Classe Utilitaire HibernateUtil.java
package util;
import org.hibernate.*;
import org.hibernate.cfg.*;
public class HibernateUtil {
public static final SessionFactory sessionFactory;
static {
try {
// Cration de la SessionFactory partir de hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
//public static final ThreadLocal session = new ThreadLocal();
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Configurer le systme de logs
Nous avons finalement besoin de configurer le systme de
"logs".
Cette opration nest pas obligatoire. Mais elle permet au
dveloppeur dafficher sur une sortie les messages fournis
par Hibernate lors de son excution.
Ce qui permet de rendre transparente la couche logicielle
de Hibernate.
Hibernate utilise commons-logging et vous laisse le choix
entre log4j et le systme de logs du JDK 1.4.
La plupart des dveloppeurs prfrent log4j
copiez log4j.properties de la distribution d'Hibernate (il est
dans le rpertoire etc/) dans votre rpertoire src.
Ce fichier contient une configuration du systme de logs qui
peut tre personnalise par lutilisateur.
L'infrastructure est complte et nous sommes prts
effectuer un travail rel avec Hibernate.
Crer des Runions
import org.hibernate.Session; import java.util.Date;
import util.HibernateUtil; import gest.*;
public class ReunionManager {
public void addReunion(String titre, Date dateR) {
Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Reunion r = new Reunion();
r.setTitreReunion(titre);
r.setDateReunion(dateR);
session.save(r);
session.getTransaction().commit();
}
public static void main(String[] args) {
ReunionManager gestManager = new ReunionManager();
gestManager.addReunion("conseil",new Date());
HibernateUtil.getSessionFactory().close();
}

}
Aprs Excution
Les messages suivants saffichent dans la sortie standard
Hibernate: select max(ID_REUNION) from REUNIONS
Hibernate: insert into REUNIONS (DATE_REUNION,
titreReunion, ID_REUNION) values (?, ?, ?)
La structure de la table Reunions serait cre.
Et un enregistrement est insr dans la base de donnes.
Lister le contenu de la table Reunions
On ajoute la mthode suivante la
classe ReunionManager
public List listReunions() {
Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List result = session.createQuery("from Reunion").list();
session.getTransaction().commit();
return result;
}

Afficher dans la mthode main
public static void main(String[] args) {
ReunionManager gestManager = new ReunionManager();
//gestManager.addReunion("conseil",new Date());
//gestManager.addReunion("Compte rendue",new Date());
//gestManager.addReunion("dlibration",new Date());
List listR=gestManager.listReunions();
Iterator lesR=listR.iterator();
while(lesR.hasNext()){
Reunion r=(Reunion)lesR.next();
System.out.println(r.getIdReunion()+"--"
+r.getTitreReunion()+"--"
+r.getDateReunion()
);
}
HibernateUtil.getSessionFactory().close();
}
Mapper les associations
Nous avons mapp une classe d'une
entit persistante vers une table.
Partons de l et ajoutons quelques
associations de classe.
D'abord nous ajouterons des
personnes notre application, et
stockerons une liste de runions
auxquelles ils participent.
Mapper les associations
Rappelons le problme : Une Runion concerne
plusieurs personnes et une personne peut participer
plusieurs runions.
Association Unidirectionnelle base
sur un Set
Si on suppose que dans notre problme, nous aurons
besoin de savoir pour chaque Personne charge, quelles
sont les diffrentes runions aux quelles il a particip.
Il est claire que notre association peut tre modlise
unidirectionnelle.
Mapper la classe Personne
Une personne est caractrise
par les attributs privs:
Son identifiant
Son nom
Son prnom
et son age.
Une collection Set de
runions.
Les autres mthodes sont des
accesseurs et les mutateurs.
Sans oublier le constructeur
par dfaut.
Personne.java
package gest;
import java.util.*;
public class Personne {
private Long idPersonne;
private String nomPersonne;
private String prenomPersonne;
private int age;
private Set reunions=new HashSet();
.
// getters and setters
.

}
Fichier de mapping de la classe
Personne : Personne.hbm.xml
Avant dcrire notre fichier xml de mapping, il est
important de savoir ce stade, comment serait modliser
notre problme dans une base de donnes relationnelle.
Nous avons une association plusieurs plusieurs non
porteuse de proprit.
Le schma de la base de donnes relationnelle serait le
suivant :
Fichier de mapping de la classe
Personne : Personne.hbm.xml
<hibernate-mapping>
<class name="gest.Personne" table="PERSONNES">
<id name="idPersonne" column="ID_PERSONNE">
<generator class="increment"/>
</id>
<property name="nomPersonne" column="NOM_PERSONNE"/>
<property name="age" column="AGE"/>
<set name="reunions" table="PERS_REUNIONS">
<key column="ID_PERSONNE"/>
<many-to-many column="ID_REUNION"
class="gest.Reunion"/>
</set>
</class>
</hibernate-mapping>
Personne.hbm.xml
Ce fichier doit tre galement plac
dans le mme dossier que la classe
Personne.java c'est--dire src\gest.
Ajouter ce fichier de mapping dans le
fichier de configuration de
hibernate Hibernate.cfg.xml :
<mapping resource="gest/Reunion.hbm.xml"/>
<mapping resource="gest/Personne.hbm.xml"/>
Mthode pour ajouter une nouvelle
Personne
public void addPersonne(String nom, String prenom,int age) {
Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Personne p = new Personne();
p.setNomPersonne(nom);
p.setPrenomPeronne(prenom);
p.setAge(age);
session.save(p);
session.getTransaction().commit();
}
Mthode pour ajouter Une runion
une personne
public void addReunionToPersonne(Long idPersonne, Long idReunion) {
Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
// Charger une personne
Personne p = (Personne) session.load(Personne.class, idPersonne);
// Charger une runion
Reunion r = (Reunion) session.load(Reunion.class, idReunion);
// Ajouter la runion r la collection reunions de la personne p
p.getReunions().add(r);
session.getTransaction().commit();
}
Aprs le chargement d'une personne et d'une runion,
modifiez simplement la collection en utilisant les
mthodes normales de la collection.
Ici, nous utilisons la mthode add de la collection SET
pour ajouter la runion la collection reunions de
lobjet personne.
Comme vous pouvez le voir, il n'y a pas d'appel
explicite update() ou save(), Hibernate dtecte
automatiquement que la collection a t modifie et a
besoin d'tre mise jour.
Ceci est appel la vrification sale automatique
("automatic dirty checking"),
Mthode pour ajouter Une runion
une personne
et vous pouvez aussi l'essayer en modifiant le nom ou
la proprit date de n'importe lequel de vos objets.
Tant qu'ils sont dans un tat persistant, c'est--dire,
lis une Session Hibernate particulire (c--d qu'ils
ont juste t chargs ou sauvegards dans une unit
de travail), Hibernate surveille les changements et
excute le SQL correspondant.
Le processus de synchronisation de l'tat de la
mmoire avec la base de donnes la fin d'une unit
de travail, est appel flushing.
Dans notre code, l'unit de travail s'achve par un
commit (ou rollback) de la transaction avec la base de
donnes - comme dfini par notre option thread de
configuration pour la classe CurrentSessionContext.
Mthode pour ajouter Une runion
une personne
public Personne getPersonne(Long idPersonne) {
Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Personne p = (Personne) session.load(Personne.class,idPersonne);
return p;
}
Mthode qui retourne une personne
charge en utilisant son identifiant
Avec cette mthode, nous allons vrifier que si on
charge une personne, hibernate charge
automatiquement tous les objets Reunion de cette
personne dans la collection reunions.



Tester Notre travail
1- Crer des runions

ReunionManager gestManager = new ReunionManager();

// Cration des runions.
System.out.println("Cration des runions");

gestManager.addReunion("conseil",new Date());
gestManager.addReunion("Compte rendue",new Date());
gestManager.addReunion("dlibration",new Date());
Tester Notre travail
2- Afficher toutes les runions

List listR=gestManager.listReunions();
Iterator lesR=listR.iterator();
while(lesR.hasNext()){
Reunion r=(Reunion)lesR.next();
System.out.println(r.getIdReunion()+"--"
+r.getTitreReunion()+"--"
+r.getDateReunion()
);
}
Tester Notre travail
3- Crer des personnes

gestManager.addPersonne("Jihad","hassan",25);
gestManager.addPersonne("mandari","latifa",22);
gestManager.addPersonne("Talal","yassine",23);
Tester Notre travail
4- Ajouter des runions aux
personnes

gestManager.addReunionToPersonne(new Long(1),new Long(1));
gestManager.addReunionToPersonne(new Long(2),new Long(1));
gestManager.addReunionToPersonne(new Long(3),new Long(1));
gestManager.addReunionToPersonne(new Long(1),new Long(2));
gestManager.addReunionToPersonne(new Long(3),new Long(2));
Tester Notre travail
5- Consulter une personne
Personne p=gestManager.getPersonne(new Long(1));
System.out.println(p.getNomPersonne()+"--"+
p.getPrenomPersonne()+"--"+p.getAge());
System.out.println("Runions auquelles a particip cette
personne");
Iterator reunions=p.getReunions().iterator();
while(reunions.hasNext()){
Reunion r=(Reunion)reunions.next();
System.out.println(r.getTitreReunion()+"--"+
r.getDateReunion());
}
Association bidirectionnelle
Dans lexemple prcdent, nous avons
mapp lassociation entre la classe Personne
et Reunion dans un seul sens.
Ce qui nous permet dajouter des runions
une personne, et en chargeant une personne,
on peut connatre toutes les runions
auxquelles a particip cette personne.
Si nous souhaitons galement crer une
runion et lui ajouter des personne,
et si nous voulions quune fois quon charge
une runion, on veut connatre toutes les
personnes qui participent cette runion, Il
faudrait galement mapper lassociation
entre les deux classe dans lautre sens.
Association bidirectionnelle
Dans ce cas lassociation se traduit par :
Cration dune collection dans la classe Personne qui
permet de stocker les runions. Cette collection a t
dj cre dans le cas prcdent. Nous avons appel
cette collection reunions et elle est de type Set.
Cration dune collection dans la classe Reunion qui
permet dassocier des personnes une runion. Cette
collection est de type Set et sera appele personnes.
Association bidirectionnelle
Nous allons faire fonctionner l'association
entre une personne et une runion partir
des deux cts en Java.
Bien sr, le schma de la base de donnes
ne change pas, nous avons toujours une
pluralit many-to-many.
Une base de donnes relationnelle est plus
flexible qu'un langage de programmation
orient objet, donc elle n'a pas besoin de
direction de navigation
Association bidirectionnelle
D'abord, ajouter une collection de
participants la classe Reunion :
private Set personnes = new HashSet();
public Set getPersonnes() {
return personnes;
}
public void setPersonnes(Set personnes)
{
this.personnes = personnes;
}
Association bidirectionnelle
Maintenant mapper ce ct de
l'association aussi, dans
Reunion.hbm.xml.
<set name="personnes"
table="PERS_REUNIONS"inverse="true">
<key column="ID_REUNION"/>
<many-to-many column="ID_PERSONNE"
class="gest.Personne"/>
</set>
Travailler avec des liens bidirectionnels
Beaucoup de dveloppeurs programment de manire
dfensive et crent des mthodes de gestion de lien
pour affecter correctement les deux cts, par exemple
dans Person :
protected Set getReunions() {
return reunions;
}
protected void setReunions(Set reunions) {
this.reunions = reunions;
}
public void addReunion(Reunion reunion) {
this.getReunions().add(reunion);
reunion.getPersonnes().add(this);
}
public void removeReunion(Reunion reunion) {
this.getReunions().remove(reunion);
reunion.getPersonnes().remove(this);
}
Association bidirectionnelle de type
one-to-many et many-to-one
Maintenant, nous allons nous intresser un
type dassociation trs frquente qui est un
plusieurs dans les deux sens.
Prenons lexemple dun client qui possde
plusieurs factures et chaque facture appartient
un client.
Travailler avec des liens bidirectionnels
Cette association se traduit par :
La cration dune collection dobjets Facture
dans la classe Client
La cration dune rfrence (handle) un
objet Client dans la classe Facture.
Cette manire de modliser notre
problme nous permet un moment
donn de connatre le client dune
facture donne et les factures dun client
donn.
Travailler avec des liens bidirectionnels
Du cot de la base de donnes, ce genre
dassociation se traduit par :
la cration de deux tables CLIENTS et FACTURES
avec dune cl trangre, qui reprsente le client,
dans la table FACTURES.
Diagramme de classes
factures
* 1
Client.java
package mod.fact;
import java.util.*;
public class Client {
private Long idClient;
private String nomClient;
private String prenomClient;
private String societe;
private String adresse;
private Set factures=new HashSet();
public Client(){

}
public void addFacture(Facture f){
this.factures.add(f);
f.setClient(this);
}
protected Set getFactures() {
return factures;
}
protected void setFactures(Set factures) {
this.factures = factures;
}
..
}
Facture.java
package mod.fact;
import java.util.Date;
public class Facture {
private Long idFacture;
private Date dateFacture;
private double montant;
private Client client;
public Facture(){}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
//client.getFactures().add(this);
}

}
Mapper la classe Client
<hibernate-mapping>
<class name="mod.fact.Client" table="clients" >
<id name="idClient" column="ID_CLIENT">
<generator class="increment"/>
</id>
<property name="nomClient" column="NOM_CLIENT"/>
<property name="prenomClient" column="PRENOM_CLIENT"/>
<property name="societe" column="SOCIETE"/>
<property name="adresse" column="ADRESSE"/>
<set name="factures" inverse="true">
<key column="ID_CLIENT"/>
<one-to-many class="mod.fact.Facture"/>
</set>
</class>
</hibernate-mapping>
Mapper la classe Facture
<hibernate-mapping>
<class name="mod.fact.Facture">
<id name="idFacture" column="ID_FACTURE">
<generator class="increment"/>
</id>
<property name="dateFacture"
column="DATE_FACTURE"/>
<property name="montant" column="MONTANT"/>
<many-to-one name="client"
column="ID_CLIENT"/>
</class>
</hibernate-mapping>
Ajouter un client
public void addClient(String nom,String prenom,
String societe, String adresse){
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Client cli=new Client();
cli.setNomClient(nom);
cli.setPrenomClient(prenom);
cli.setSociete(societe);
cli.setAdresse(adresse);
session.save(cli);
session.getTransaction().commit();
}
Ajouter une facture
public void addFacture(Date dateFact,double montant,Long idClient){
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Client cli=(Client)session.load(Client.class,idClient);
Facture fact=new Facture();
fact.setDateFacture(dateFact);
fact.setMontant(montant);
cli.addFacture(fact);// fact.setClient(cli);
session.save(fact);
session.getTransaction().commit();
}
Association plusieurs plusieurs
avec des proprits.
Nous avons dj vu au dbut de ce cours comment
mapper une association many to many sans proprit
Considrons lexemple suivant : ( Une personne
participe plusieurs runions et une runion concerne
plusieurs personnes)
Considrons lexemple suivant:
Un client peut passer plusieurs commandes.
Chaque commande concerne plusieurs produits avec
une quantit de chaque produit.
Chaque produit peut appartenir plusieurs
commandes.
Il est clair que lassociation concerne entre
Commande et Produit est de type many-to-many avec
une proprit quantit pour cette association.
Association plusieurs plusieurs
avec des proprits.
Diagramme de classes
1 *
1 *
* 1
Association plusieurs plusieurs
avec des proprits.
En Modle relationnel, notre problme est
modlis par une base de donnes 4
tables :
CLIENT (ID_CLIENT, NOM_CLIENT, SOCIETE)
COMMANDE ( ID_COMMANDE,
DATE_COMMANDE, #ID_CLIENT)
COMPOSANTES (ID_COMPOSANTE,
#ID_COMMANDE, #ID_PRODUIT,
QUANTITE)
PRODUITS (ID_PRODUIT, DESIGNATION,
PRIX, DISPONIBLE, QUANTITE_STOCK)
Mapping objet relationnel
Client.hbm.xml
<hibernate-mapping>
<class name="gest.cmd.Client" table="CLIENTS">
<id name="idClient" column="ID_CLIENT">
<generator class="native"/>
</id>
<property name="nomClient" column="NOM_CLIENT"/>
<property name="societe" column="SOCIETE"/>
<set name="commandes" inverse="true">
<key column="ID_CLIENT"/>
<one-to-many class="gest.cmd.Commande"/>
</set>
</class>
</hibernate-mapping>
Mapping objet relationnel
Commande.hbm.xml
<hibernate-mapping>
<class name="gest.cmd.Commande" table="COMMANDES">
<id name="idCommande" column="ID_COMMANDE">
<generator class="native"/>
</id>
<property name="dateCommande" column="DATE_COMMANDE"/>
<many-to-one name="client" column="ID_CLIENT"/>
<list name="lesComposantes" table="COMPOSANTES">
<key column="ID_COMMANDE"/>
<list-index column="ID_COMPOSANTE"/>
<composite-element class="gest.cmd.Composante">
<property name="quantite" column="QUANTITE"/>
<many-to-one name="produit" column="ID_PRODUIT"
class="gest.cmd.Produit"/>
</composite-element>
</list>
</class>
</hibernate-mapping>
Mapping objet relationnel
Produit.hbm.xml
<hibernate-mapping>
<class name="gest.cmd.Produit" table="PRODUITS">
<id name="idProduit" column="ID_PRODUIT">
<generator class="native"/>
</id>
<property name="designation"/>
<property name="quantite"/>
<property name="disponible"/>
<property name="prix"/>
</class>
</hibernate-mapping>
Ajouter un client
public void addClient(String nom,String societe){
Session
session=HibernateUtil.getSessionFactory().getCurrent
Session();
session.beginTransaction();
Client cli=new Client();
cli.setNomClient(nom);
cli.setSociete(societe);
session.save(cli);
session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
}
Ajouter un produit
public void addProduit(String des, double prix,boolean dispo, int quantite){
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Produit p=new Produit();
p.setDesignation(des);
p.setQuantite(quantite);
p.setDisponible(dispo);
p.setPrix(prix);
session.save(p);
session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
}
Ajouter une commande
public void addCommande(Date date,Long idClient){
Session
session=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Client client=(Client)session.load(Client.class,idClient);
Commande comm=new Commande();
comm.setDateCommande(date);
client.addCommande(comm);
session.save(comm);
session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
}
Ajouter un produit une
commande
public void addProduitToCommande(Long idCommande,Long idProduit,int
quantite){
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Commande comm=(Commande)session.load(Commande.class,idCommande);
Produit prod=(Produit)session.load(Produit.class,idProduit);
Composante compo=new Composante();
compo.setQuantite(quantite);
compo.setProduit(prod);
comm.getLesComposantes().add(compo);
session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
}
Charger une commande
public Commande chargerCommande(Long idCommande){
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Commande comm=
(Commande)session.load(Commande.class,idCommande);
return comm;
}
Exemple dapplication web
Action Form
CommandeForm.java:
import java.util.Iterator;
import org.apache.struts.action.*;
import gest.cmd.*;
public class CommandeForm extends ActionForm {
private int idCommande=1;
private Commande commande=new Commande();
private Client client=new Client();
private Iterator lesComposantes;

public Client getClient() {
return client;
}
public Commande getCommande() {
return commande;
}
public void setCommande(Commande commande) {
this.commande = commande;
}
.
}

Action
CommandeAction.java:
Mthode execute:
.
CommandeForm cf=(CommandeForm)form;
Long idC=new Long(cf.getIdCommande());
GestCommandes gest=new GestCommandes();
Commande comm=gest.chargerCommande(idC);
cf.setCommande(comm);
cf.setClient(comm.getClient());
cf.setLesComposantes(comm.getLesComposantes().iterator());
return map.findForward("commandes");
}
}
Struts-config.xml
<struts-config>
<form-beans>
<form-bean name="cmdForm" type="CommandeForm"/>
</form-beans>
<global-forwards>
<forward name="commandes" path="/Commandes.jsp"/>
</global-forwards>
<action-mappings>
<action path="/comm"
name="cmdForm"
type="CommandeAction"
scope="request"
/>
</action-mappings>
<message-resources parameter="ressources.RessApp"/>
</struts-config>
Commandes.jsp
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<html>
<head>
<title>Commandes</title>
</head>
<body bgcolor="#FFFFFF">
<hr>
<h1>Commandes:</h1>
<html:form action="comm.do" >
<hr>
Numro de commande:
<html:text property="idCommande"/>
<html:submit value="Chercher" />
</html:form>
Commandes.jsp
<hr>
Date de Commande:
<bean:write name="cmdForm" property="commande.dateCommande" />
<hr>
<h1>Client:</h1><li>Nom du Client:
<bean:write name="cmdForm" property="client.nomClient" /></li>
<li>Socit:
<bean:write name="cmdForm" property="client.societe" /></li>
<hr>
Commandes.jsp
<h1>Produits</h1>
<table border='1' width='90%'>
<tr> <td>Id Produit</td> <td>Dsignation</td> <td>Prix</td>
<td>Quantit</td><td>Montant</td> </tr>
<%
double montant;
double total=0;
%>
<logic:iterate id="composante" name="cmdForm"
property="lesComposantes" type="gest.cmd.Composante" >
<tr>
<td><bean:write name="composante" property="produit.idProduit" /></td>
<td><bean:write name="composante" property="produit.designation" /></td>
<td><bean:write name="composante" property="produit.prix" /></td>
<td><bean:write name="composante" property="quantite" /></td>
<%
montant=composante.getProduit().getPrix() * composante.getQuantite();
total+=montant;
%>
<td><%=montant%></td>
</tr>
</logic:iterate>
<tr><td></td><td></td><td></td><td>Total</td><td><%=total%></td>
</tr></table></body></html>
Mapper lhritage
Hibernate supporte les trois
stratgies d'hritage de base :
une table par hirarchie de classe (table
per class hierarchy)
une table par classe fille (table per
subclass)
une table par classe concrte (table per
concrete class)

Exemple
Base de donnes : Table par hirarchie
Table clients
Table comptes
Table Oprations
Client.hbm.xml
<hibernate-mapping>
<class name="net.youssfi.comptes.Client" table="CLIENTS">
<id name="idClient" column="ID_CLIENT">
<generator class="native"/>
</id>
<property name="nom" column="NOM"/>
<property name="adresse" column="ADRESSE"/>
<set name="comptes" inverse="true">
<key column="ID_CLIENT"/>
<one-to-many class="net.youssfi.comptes.Compte"/>
</set>
</class>
</hibernate-mapping>
Compte.hbm.xml
<hibernate-mapping>
<class name="net.youssfi.comptes.Compte" table="COMPTES">
<id name="idCompte" column="ID_COMPTE">
<generator class="native"/>
</id>
<discriminator column="COMPTE_TYPE" type="string"/>
<property name="solde"/>
<property name="decouvert"/>
<many-to-one name="client" column="ID_CLIENT"/>
<set name="operations" inverse="true" table="OPERATIONS" >
<key column="ID_COMPTE" update="true"/>
<one-to-many class="net.youssfi.comptes.Operation"/>
</set>
<subclass name="net.youssfi.comptes.CompteB" discriminator-value="B">
</subclass>
<subclass name="net.youssfi.comptes.CompteEpargne" discriminator-value="E">
<property name="taux" column="TAUX"/>
</subclass>
</class>
</hibernate-mapping>
Operation.hbm.xml
<hibernate-mapping>
<class name="net.youssfi.comptes.Operation"
table="OPERATIONS">
<id name="idOperation">
<generator class="native"/>
</id>
<discriminator column="OPERATION_TYPE" type="string"/>
<property name="dateOperation"/>
<many-to-one name="compte" column="ID_COMPTE"/>
<subclass name="net.youssfi.comptes.OperationVersement"
discriminator-value="V">
<property name="montantVersement"/>
</subclass>
<subclass name="net.youssfi.comptes.OperationRetrait"
discriminator-value="R">
<property name="montantRetrait"/>
</subclass>
</class>
</hibernate-mapping>
Ajouter un client
public void addClient(String nom,String add){
Session
session=HibernateUtil.sessionFactory.getCurrentSession();
session.beginTransaction();
Client cl=new Client();
cl.setNom(nom);
cl.setAdresse(add);
session.save(cl);
session.getTransaction().commit();
}
Ajouter un CompteB
public void addCompteB(Long idClient, double solde){
Session
session=HibernateUtil.sessionFactory.getCurrentSession();
session.beginTransaction();
Client cli=(Client)session.load(Client.class,idClient);
CompteB cb=new CompteB();
cb.setSolde(solde);
cb.setClient(cli);
session.save(cb);
session.getTransaction().commit();

}
Ajouter un CompteEpargne
public void addCompteEpargne(Long idClient, double
solde,double taux){
Session
session=HibernateUtil.sessionFactory.getCurrentSession();
session.beginTransaction();
Client cli=(Client)session.load(Client.class,idClient);
CompteEpargne cb=new CompteEpargne();
cb.setSolde(solde);
cb.setTaux(taux);
cb.setClient(cli);
session.save(cb);
session.getTransaction().commit();
}
Verser un montant dans un compte
public void verser(Long idCompte, double montant){
Session
session=HibernateUtil.sessionFactory.getCurrentSession();
session.beginTransaction();
Compte
cpte=(Compte)session.load(Compte.class,idCompte);
OperationVersement op=new OperationVersement();
op.setDateOperation(new Date());
op.setMontantVersement(montant);
cpte.verser(op.getMontantVersement());
cpte.addOperation(op);
session.save(op);
session.update(cpte);
session.getTransaction().commit();
}
Retirer un montant
public void retirer(Long idCompte, double montant){
Session
session=HibernateUtil.sessionFactory.getCurrentSession();
session.beginTransaction();
Compte
cpte=(Compte)session.load(Compte.class,idCompte);
OperationRetrait op=new OperationRetrait();
op.setDateOperation(new Date());
op.setMontantRetrait(montant);
cpte.retirer(op.getMontantRetrait());
cpte.addOperation(op);
session.save(op);
session.update(cpte);
session.getTransaction().commit();
}
Charger un compte
public Compte getCompte(Long idCompte){
Session
session=HibernateUtil.sessionFactory.getCurrentSession();
session.beginTransaction();
Compte cpte=(Compte)session.load(Compte.class,idCompte);
return cpte;
}
Exemple test
public static void main(String[] args) {

GestComptes gc=new GestComptes();
gc.addClient("youssfi","Mohammedia");
gc.addClient("Fadili","Casa");
gc.addCompteB(new Long(1),6000);
gc.verser(new Long(1),7000);
gc.retirer(new Long(1),2000);

Compte cpte=gc.getCompte(new Long(1));
System.out.println("Compte
code="+cpte.getIdCompte()+" Solde="+cpte.getSolde());
System.out.println("Opration:");

Exemple test (suite)
Iterator lesOp=cpte.getOperations().iterator();
while(lesOp.hasNext()){
Operation op=(Operation)lesOp.next();
System.out.print(op.getIdOperation()+"--"+
op.getDateOperation()+"--");
if(op instanceof OperationVersement )

System.out.println(((OperationVersement)op).getMontantVers
ement()+"-- 00.00"
);
else
System.out.println(" 00.00 ---"+
((OperationRetrait)op).getMontantRetrait());

}
}