Vous êtes sur la page 1sur 83

Information Systems Research Group

Département d'informatique
Université de Fribourg, Suisse
http://diuf.unifr.ch/

Compiere
Installation et adaptation avec Hibernate

Travail de Bachelor

Thibaut Schorderet
Septembre 2005

Supervision :
Dr. Henrik Stormer
Nicolas Werro
i

Abstract
Les logiciels Open Source et gratuits suscitent un intérêt toujours plus fort
chez les privés et les entreprises. Eectivement, le fait de pourvoir trouver
un programme gratuit comprenant des fonctionnalités quasiment identiques
à celles d'un logiciel professionnel développé par de grandes rmes est un
point très intéressant. Compiere, élément central de cette thèse, est un logi-
ciel Open Source et gratuit qui rivalise avec d'autres produits payants du
marché. Comme pour la plupart des logiciels de gestion, Compiere interagit
avec une base de données. Ces dernières sont très souvent indispensables dans
l'architecture d'un logiciel et se sont beaucoup développées ces dernières an-
nées ayant pour conséquence l'apparition sur le marché de diérents types de
systèmes de gestion de bases de données. Inévitablement apparaissent alors
des problèmes de compatibilité si l'on veut combiner ensemble ces diérents
systèmes. Comme c'est le cas pour Compiere, beaucoup de logiciels sont
actuellement dépendant d'un certain type de base de données, limitant leur
portabilité. A l'avenir, l'idéal serait la possibilité d'une adaptation directe et
simple de tout logiciel aux divers systèmes de gestion de bases de données.
A l'heure actuelle Hibernate apporte des solutions très intéressantes à cette
approche.
TABLE DES MATIÈRES ii

Table des matières


1 Introduction 1
1.1 Motivations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.3 Structure de la documentation . . . . . . . . . . . . . . . . . . . . . . . . . . 1


1.4 Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Compiere 3
2.1 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1.1 Technologies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1.2 Fonctionnalités principales . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.3 Avantages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.4 Installation de Compiere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3 Code source 6
3.1 CVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2 Généralités, structures des classes . . . . . . . . . . . . . . . . . . . . . . . . 7

3.3 Packages, classes et méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . 7


3.3.1 Notation UML utilisée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.3.2 Packages de Compiere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.4 Base de données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.4.1 Création de la base de données . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.4.2 Eléments de la base de données . . . . . . . . . . . . . . . . . . . . . . . . . 11

4 Théorie ORM 14
4.1 Dénition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.1.1 Purement relationnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.1.2 Light objet mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.1.3 Medium object mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.1.4 Full object mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2 Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2.1 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2.2 Avantages d'Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2.3 Hibernate : les complications . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5 Utilisation d'Hibernate 19
5.1 Installation d'Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5.1.1 Installation du plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5.2 Installation de la base de données . . . . . . . . . . . . . . . . . . . . . . . . 20
5.2.1 Installation de Hsqldb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5.3 Fichiers à réaliser pour employer Hibernate . . . . . . . . . . . . . . . . 23
5.3.1 Fichier de conguration d'Hibernate . . . . . . . . . . . . . . . . . . . . . 23
5.3.2 Document de mapping objet / relationnel . . . . . . . . . . . . . . . . . . 28
5.3.3 Gestion de la persistance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.3.4 Création du chier Tested.java . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.4 Exemple de mapping pour Compiere . . . . . . . . . . . . . . . . . . . . . 38
TABLE DES MATIÈRES iii

6 Conclusion 45
6.1 Expériences faites durant la réalisation du projet . . . . . . . . . . . . 45

6.2 Résultats du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

Annexe A: Tutorial d'installation 47

Annexe B: Package org.compiere.db 57

Annexe C : Exemple de schéma ER - module Country 70

Annexe D : Logiciels utilisés 76


LIST OF FIGURES iv

List of Figures
2.1 Architecture client-serveur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.1 Notations UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2 Vue aérienne du schéma de la base de données de Compiere . . . . . . . . . . . . . . . . 12
4.1 Architecture d'Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5.1 HSQL Database Manager login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5.2 HSQL Database Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
5.3 Environnement non géré . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5.4 Environnement non géré avec Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5.5 Interface de création du chier de conguration . . . . . . . . . . . . . . . . . . . . . . . 26
5.6 API d'Hibernate dans une architecture en couches . . . . . . . . . . . . . . . . . . . . . 32
5.7 Enregistrement de l'objet dans la table 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
A.1 Interface de conguration du serveur Compiere . . . . . . . . . . . . . . . . . . . . . . . 49
A.2 Résultat du script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A.3 Identication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
A.4 Paramètres de connexion à la base de données . . . . . . . . . . . . . . . . . . . . . . . . 54
A.5 Paramètres de connexion à l'application . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
B.1 Package org.compiere.db . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
B.2 Classe CConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
B.3 Classe Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
B.4 Classe CreateCompiere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
B.5 Classe TestConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
C.1 Modèle logique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
LIST OF FIGURES v

Remerciements
Avant de rentrer dans le vif du sujet de cette thèse de bachelor, j'aimerais remercier
mes deux superviseurs du projet : Dr Henrik Stormer et Nicolas Werro pour leur
implication dans ce projet et pour leur rigoureuse correction du travail. Merci également
au Professeur Andreas Meier, titulaire du groupe de recherche 'Information Systems'.
1

1 Introduction

1.1 Motivations
Ayant à choisir un groupe de recherches dans lequel eectuer mon travail, je me suis
tout de suite tourné ver le groupe 'Information Systems'. Eectivement, j'ai un grand
intérêt pour le monde des bases de données et les cours du Professeur Andreas Meier
que j'ai suivis m'ont donné envie d'approfondir mes connaissances dans ce domaine.
Le projet qu'on m'a proposé m'a tout de suite semblé très intéressant car il perme-
ttait de travailler avec diérentes technologies, en particulier Oracle et Hibernate. Je
suis intéressé de connaître Oracle en raison de son utilisation très répandue et donc
indispensable à connaître pour travailler dans l'industrie. En ce qui concerne Hiber-
nate, je ne l'ai jamais utilisé mais j'ai déjà pu lire quelques articles consacrés à son
sujet. C'est sa puissance et sa très probable future utilisation à grande échelle qui me
motivent à l'étudier et à le tester.
Il est également très intéressant de pouvoir étudier le code source d'un logiciel de
grande envergure comme Compiere. C'est à mon avis une bonne approche pédagogique
pour voir comment les développeurs professionnels structurent leurs logiciels.

1.2 Objectifs
Le but de ce projet est d'étudier s'il est possible de rendre Compiere indépendant de
la base de données avec laquelle il travaille. Eectivement, Compiere ne fonctionne à
l'heure actuelle qu'avec une base de données Oracle. Cette contrainte, assez handica-
pante, peut être éventuellement contournée avec l'emploi d'Hibernate qui est un outil
de mapping objet / relationnel. Ce dernier doit permettre de récupérer des objets crées
par Compiere et de mapper ces derniers dans une base de données quelconque. Le but
sera donc de récupérer un objet créer par Compiere et le mapper dans une table, c'est
à dire insérer toutes les données de l'objet dans une table relationnelle.

1.3 Structure de la documentation


La documentation est structurée en plusieurs parties. Ce projet, comportant beau-
coup d'explications techniques sur du code ainsi qu'un tutorial d'installation, la partie
Annexe est relativement importante en nombre de pages.
La première partie est intitulée 'Introduction' et comporte les objectifs et les con-
ventions du projet ainsi que les motivations m'ayant conduites à réaliser ce projet.
La deuxième partie, intitulée 'Compiere', comporte une présentation du logiciel Com-
piere, notamment ses fonctionnalités, et ses avantages. Son architecture y est également
précisément décrite.
La troisième partie, intitulée 'Code source', est une description générale du code
source de Compiere ainsi que de sa base de données. Une étude détaillée d'un package
de Compiere qui me semble important pour la réalisation de ce projet, à savoir le package
1.4 Conventions 2

org.compiere.db, se trouve en Annexes. Diérentes informations et explications y sont


également données au sujet de la base de données.
La quatrième partie, intitulée 'Théorie ORM', est une partie théorique et introduit
le concept d'ORM (object/relational mapping). Une présentation générale d'Hibernate
y est également faite.
La cinquième partie, intitulée 'Utilisation d'Hibernate', est plus orientée vers la pra-
tique en appliquant les concepts décrits dans la quatrième partie. Tous les chiers
nécessaires à l'emploi d'Hibernate y sont décrits et expliqués à l'aide d'exemples con-
crets.
La sixième partie est la Conclusion et comporte donc une synthèse du travail ainsi
que des perspectives de développement supplémentaire pour le projet.
La septième partie comporte les Annexes, à savoir diérents exemples de codes ainsi
que le tutorial d'installation de Compiere

1.4 Conventions
• La signication d'un acronyme est donnée entre parenthèses lors de sa première
apparition.

• L'URL d'un site Web est donnée en annotation de bas de page.

• La numérotation des gures correspond à leur ordre d'apparition dans une section
spécique (ex : la gure 4.1 est la première gure de la section 4).

• Le code source apparaissant dans la documentation possède une police plus petite
que le reste du texte et est en italique. Exemple : public void setDbName (String
db_name) {....}
• Les éléments importants apparaissent en gras.
3

2 Compiere

2.1 Présentation
Compiere est un logiciel Open Source destiné à la planication des ressources d'une
entreprise et contenant des outils pour la gestion des relations avec les clients. Les
ressources d'une entreprise comprennent notamment : le marketing, la distribution et les
ressources humaines. Ce logiciel est aujourd'hui le leader mondial des applications ERP
(Enterprise Resource Planning) Open Source. Un ERP est en résumé une application
qui permet de gérer toutes les ressources d'une société telles que la comptabilité, les
moyens de production, le personnel an de maximiser et de rendre plus ecace le
fonctionnement de l'entreprise.
Ces processus de planication de gestion sont à l'heure actuelle traités par des progi-
ciels complexes tels que SAP ou Peoplesoft. Le tarif d'entrée pour acheter les licences
est très élevé, ce qui fait que seules les grandes entreprises peuvent s'acquérir de telles
applications.
Avec Compiere ce problème ne se pose pas puisqu'il est gratuit et facile d'emploi. Il
comporte plusieurs modules, dont notamment un module de gestion des ventes, un por-
tail de vente et des fonctions d'achat, de stock et de logistique. La gestion comptable
et nancière est intégrée (comptabilité générale, analytique et budgétaire) et quelques
fonctions de production sont également présentes (gestion des ordres de fabrication, des
nomenclatures...).
Compiere est sous licence MPL (Mozilla Public Licence) et a été développé ini-
tialement par Jorg Janke. Cette licence permet d'avoir accès au code source, de le
dupliquer mais toute modication doit être validée par le noyau dur de la communauté
des développeurs, en l'occurrence Jorg Janke.
La première version de Compiere a vu le jour en 2000, la version actuelle étant la
2.5.2. Ce logiciel est en constante évolution, de nouvelles fonctionnalités faisant leur
apparition à chaque nouvelle version disponible.
Destiné à être le mieux adapté possible aux besoins des utilisateurs, les améliorations
et extensions des fonctionnalités sont principalement élaborées d'après les suggestions
de ces derniers. Compiere est destiné avant tout aux petites et moyennes entreprises
(PME).

2.1.1 Technologies
Compiere a été développé en Java avec une base de données Oracle et fonctionne sous
Windows, Unix et Linux. Les développeurs travaillent en ce moment sur l'indépendance
de la base de données, à savoir le fait de pouvoir utiliser Compiere avec un système de
base de données quelconque.
L'application client est écrite entièrement en Java et communique avec la base de
données via JDBC (Java Database Connectivity) et avec le serveur d'application via
RMI (Remote Method Invocation) / JNP (JBoss JNDI implementation). Le client
2.1 Présentation 4

accède aux serveurs par Internet ou Intranet. Pour la réalisation du projet, la base de
données et le serveur d'application sont installés sur la même machine. Il est évident
qu'à plus grande échelle, il est intéressant d'avoir un serveur d'application et un serveur
de bases de données distincts, les clients se connectant à distance. La base de données
Oracle demandant beaucoup de ressources matérielles, son utilisation ne pourra être
que plus optimale si une machine lui est spécialement dédiée.
Les composants du serveur d'application sont implémentés en Java basés sur la
technologie J2EE (Java 2 Platform, Enterprise Edition) et employant l'infrastructure
de serveur JBoss qui est un serveur d'applications Open Source.

Figure 2.1: Architecture client-serveur

La Figure 2.1 montre les processus et les technologies de communication entre les dif-
férents composants. Tous ces composants doivent être installés an de pouvoir utiliser
Compiere.

2.1.2 Fonctionnalités principales


Compiere dispose d'un grand nombre de fonctionnalités, dont les principales y sont
citées ci-dessous. Des modules permettant de gérer toutes les ressources d'une entreprise
y sont intégrés.

• Gestion des relations clients

• Gestion des ventes

• Gestion des achats

• Gestion des stocks

• Gestion des projets


2.1 Présentation 5

• Gestion de la comptabilité

2.1.3 Avantages
Bien qu'un des avantages principaux de Compiere réside dans sa gratuité, ce dernier
concurrence parfaitement les produits professionels payants.
Ci-dessous sont cités quelques avantages très intéressants oerts par Compiere.

• Comptabilité en temps réel

• Multi-langues, multi-sociétés

• Intégration de données en Excel

• Facilité d'utilisation

Le point fort indéniable est que Compiere peut s'adapter aux besoins spéciques de
gestion de n'importe quelle PME grâce à son architecture totalement ouverte, donc
facilement et rapidement paramétrable.

2.1.4 Installation de Compiere


L'installation de ce logiciel ERP n'étant pas triviale, un tutorial d'installation valable
pour Windows XP est présenté dans l'Annexe A. Une installation sous un système Unix
est encore plus complexe, les détails de la procédure à suivre peuvent être consultés sur
le site ociel de Compiere1 .

1 http://www.compiere.org, dernière visite le 10.11.2005


6

3 Code source

3.1 CVS
CVS (concurrent version system) est un outil employé par les développeurs pour gérer
les changements eectués dans leur code source. Ce logiciel a en mémoire à la fois la
version actuelle d'un morceau de code, mais aussi des enregistrements des anciennes
versions de ce code (avant modication). Les noms des personnes ayant fait des modi-
cations sont également enregistrés.

CVS a deux fonctions principales :


• Date de modication et identication du programmeur ayant eectué des modi-
cations sur un morceau de code spécique

• Assurer qu'un changement eectué par un développeur ne sera pas eacer par un
autre

Avec CVS, le code source est donc enregistré sur un serveur à distance et peut être
accédé par l'ensemble des développeurs. Pour y accéder depuis une machine distante, il
faut se procurer un client CVS2 , nécessaire pour pouvoir communiquer avec le serveur.
Il est également possible à toute personne intéressée de télécharger les sources via CVS,
c'est de cette manière qu'il faut s'y prendre pour télécharger le code source de Compiere.
De cette manière la dernière version du code source peut être obtenue très facilement,
CVS gérant les dates de modications des divers modules.

Etapes pour télécharger le code source de Compiere:


• Télécharger un client CVS

• Exécuter : cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/compiere login

• Exécuter : cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/compiere


co -P modulename . 'Modulename' est le nom du module à télécharger. Pour
obtenir toutes les sources de Compiere, le module à télécharger est compiere-all
Compiere-all est téléchargé sous format compressé. Il sut de le décompresser dans
le répertoire désiré une fois le téléchargement terminé. Le dossier complet comprenant
l'ensemble des sources prend alors environ 80 MB. Il sut de l'ouvrir pour voir plusieurs
sous-répertoires qui chacun contient des modules spéciques. Il y a par exemple un
répertoire nommé db (database) pour la gestion de tout ce qui concerne la base de don-
nées, un autre nommé install qui, comme son nom l'indique fort bien, gère l'installation
de Compiere.
2 WinCvs téléchargeable à l'adresse suivante : http://www.wincvs.org/ , dernière visite le 11.11.2005
3.2 Généralités, structures des classes 7

An d'étudier les sources, il faut à l'aide d'un éditeur, ouvrir le projet Compiere.
Dans mon cas, j'utilise Eclipse3 . Tous les modules et fonctionnalités sont regroupés en
module, tout le code source est désormais disponible !

3.2 Généralités, structures des classes


Le code source est écrit en Java. Le répertoire nommé Compiere-all contient l'entier
des sources et le code est considéré comme bien écrit et documenté.

Chaque classe Java ne peut être employée que via le respect de la version 1.1 de la
licence de Compiere4 . C'est une licence classique, spéciant les rôles de chacune des
personnes impliquées dans le projet. Il est par exemple signalé qu'une version modiée
de Compiere par un programmeur quelconque, reste propriété intégrante des fonda-
teurs de Compiere et que seuls ces derniers peuvent par exemple donner l'accord nal
pour commercialiser une nouvelle version de Compiere comportant des modications
importantes.

Toutes les classes contiennent également le nom de leur auteur, Jorg Janke ayant écrit
l'intégralité des sources originales. La version du chier est également donnée.

Structure des classes :


**Infos, copyrights**
**auteur**
**version**
package nom du package auquel appartient la classe;
import nom des composants à importer ;
public class nom classe {
...
code
...
}

3.3 Packages, classes et méthodes


Compiere est composé de 33 packages pour environ 1400 classes. L'ensemble de ces
packages peut-être consulté à travers une API complète de Compiere5 en version HTML.
Ci-dessous seront cités ces diérents packages, accompagnés d'une courte description.
Il ne serait pas intéressant d'expliquer en détails chaque package, ceci prendrait évidem-
ment beaucoup trop de temps et de place.
3 http://www.eclipse.org/ , dernière visite le 13.11.2005
4 http://www.compiere.org/license.html, dernière visite le 10.11.2005
5 http://www.compiere.org/documentation/API/index.html, dernière visite le 02.11.2005
3.3 Packages, classes et méthodes 8

Cependant, citer tous les packages composant Compiere avec une très brève explication
de leur fonctionnalité principale est utile an de se rendre compte de la structure prin-
cipale, de l'ossature du programme.
Un package (org.compiere.db) qui me semble important dans le cadre de ce projet sera
décrit en détails. Dans ce package seront décrites les classes et méthodes les plus impor-
tantes et utiles pour la réalisation du projet. Une représentation graphique est donnée
pour le package choisi ainsi que pour les classes. Cette notation utilisée est conforme à
UML (Unied Modeling Language).

3.3.1 Notation UML utilisée


Les classes du code source présentées dans la partie l'Annexe A sont conforment à
la notation UML qui est un outil de modélisation consistant à créer une représenta-
tion simpliée d'un problème, appelée un modèle. Grâce au modèle il est possible de
représenter simplement un problème, un concept et le simuler.
La représentaion du système est appelée une vue et est constituée d'un ou plusieurs
diagrammes. On distingue habituellement 2 types de vues : les vues statiques et les
vues dynamiques.
Les vues statiques représentent le système physiquement à l'aide par exemple des dia-
grammes d'objets et des diagrammes de classes.
Les vues dynamiques montrent le fonctionnement du système à l'aide notamment des
diagrammes de séquence et de collaboration.
Certains détails de représentation changent selon les standards utilisés par les
développeurs, mais le fondement reste identique.
Les diagrammes employés sont de type statique : diagrammes de classe. Les liens entre
les classes ne sont pas représentés pour des raisons de place et de complexité. Sont
représentés pour chaque classe décrite uniquement les méthodes et attributs propres à
cette classe.

Figure 3.1: Notations UML

Le rectangle de gauche de la Figure 3.1 représente une classe, le haut du rectangle


comporte son nom. Sous 'attributes' se trouvent tous les attributs de la classe: les
3.3 Packages, classes et méthodes 9

champs de classes (déclarés static) et les champs d'instance (propres aux objets crées).

Exemple de champ de classe(1) et de champ d'instance(2) :

• (1) public static nal double PI = 3.14159 ;

• (2) public double r ;

Sous 'operations' se trouvent le constructeur de la classe dans le cas où il a été redéni


ainsi que toutes les méthodes de la classe, que ça soient des méthodes de classes ou des
méthodes d'instance. Comme pour les champs, les méthodes de classe sont spéciques
à la classe en question et sont déclarées à l'aide du mot réservé static, tandis que les
méthodes d'instances sont propres aux objets générés.

La gure de droite représentant un rectangle assorti d'une petite étiquette sur le haut
à gauche dénit un package. Son nom se trouve sous l'étiquette. Classes comprend
l'ensemble des classes comprises dans ce package. Lorsqu'un package contient des sous
packages, le nom de ces dernier se trouve entre le nom du package et le nom des classes
composant le package. Un exemple de sous-package : package api.spec.

Dans le cas où un package contient une ou plusieurs interfaces, le nom de cette/ces


dernières est également située dans Classes mais le nom de l'interface est inscrit en
italique. Borland Together Designer6 a été employé pour générer ces graphiques de
classes et packages sous forme UML.
Il peut être téléchargé et utilisé pour une période d'essai. Ce software permet entre
autres de générer le code java correspondant au schéma UML réalisé. Le but est en fait
de générer le squelette, la structure du code, ce dernier doit par la suite être complété
manuellement par les programmeurs.

3.3.2 Packages de Compiere


Une description est donnée lorsque cela est possible, c'est-à-dire lorsque le package
regroupe vraiment des classes spéciques à un thème.
6 http://www.borland.com/together/ , dernière visite le 10.11.2005
3.3 Packages, classes et méthodes 10

Nom du Package Description


com.compiere.custom Contient 1 classe: CalloutUser. Divers tests
org.compiere Informations sur le démarrage du système(copyright, données statistiques...)
org.compiere.acct ***
org.compiere.apps Login pour l'applications en diverses langues
org.compiere.apps.form ELéments graphiques (Awt, Swing)
org.compiere.apps.search Infos sur les principaux composants, outils de recherche (paiements, produits...)
org.compiere.db Fournit des classes pour l'édition de la base de données
org.compiere.dbPort Fournit des outils de conversion de commandes Sql d'Oracle vers d'autres bases
de données
org.compiere.grid Gestion d'éléments graphiques
org.compiere.grid.ed Gestion d'éléments graphiques
org.compiere.grid.tree Gestion d'éléments graphiques
org.compiere.images Traite les icônes et les images (détection du format / grandeur) et en contient
un grand nombre
org.compiere.impexp Interfaces, classes pour la gestion de la banque
org.compiere.install Gère l'interface d'installation : CompiereServerSetup (voir installation Com-
piere, partie 1)
org.compiere.interfaces Interfaces pour la gestion du serveur et l'état global de Compiere
org.compiere.minigrid Classes pour eectuer des traitements directement sur les tables de la db
org.compiere.model Fonctions pour traiter /modier les tables de la base de données
org.compiere.plaf Fournit des outils pour modier l'interface utilisateur Look & Feel
org.compiere.print Pour l'impression des documents liés à Compiere (calcul nbre de pages...)
org.compiere.print.layout Gère le format de sortie de l'impression (graphique, table, image..)
org.compiere.process Fournit des processus employés au niveau serveur et éventuellement au niveau
Client
org.compiere.report.core Permet de créer des rapports automatiques de toutes sortes
org.compiere.server Gestion de la communication serveur / client
org.compiere.session Gère les sessions en cours d'exécution (vérier mots de passe ...)
org.compiere.swing Fournit des composants swing
org.compiere.tools Divers outils : gestion des chiers windows / unix, Rmi...
org.compiere.util Provides fonctions d'utilité (traductions diverses langues, sécurité, comparaison
d'objets...)
org.compiere.web Gère le serveur, moniteur (synchronization) du serveur, initialisation
org.compiere.wf Traite les Workows (WF) = déroulement d'opérations (clients, processus,
serveur...)
org.compiere.wstore Modules pour gérer le magasin online (webstore) de Compiere
http://www.compiere.com/wstore/
org.compiere.www Gère le côté web de Compiere : notamment la page de login, les menus...

Tableau 3.1 : Les packages de Compiere

Le Tableau 3.1 donne l'ensemble des packages de Compiere avec une courte descrip-
tion pour chacun. Le package org.compiere.db est en gras car il est expliqué plus en
détails dans l'Annexe B. On remarque qu'il y a beaucoup de sous-packages, comme par
exemple org.compiere.process , process étant un sous-package de Compiere.
3.4 Base de données 11

3.4 Base de données


Dans cette partie est abordée la structure physique de la base de données de Compiere.
Les éléments principaux y sont mentionnés, à savoir les tables (y compris attributs),
les clés et les relations entre ces tables.
Le schéma ER (Entity-Relationship) de la base de données se trouve dans \db
\ERModel du répertoire principal compiere-all. Pour le visualiser, il est nécessaire
d'avoir le programme Embarcadero ERStudio7 .

3.4.1 Création de la base de données


La base de données est crée via le script RUN_ImportCompiere. Le script de création
des tables se nomme Compiere.sql et est situé dans $\compiere-all\db\database
\Create. Ce chier SQL comporte la dénition de l'ensemble des tables du système.
Un exemple du contenu de ce script de création est donné dans les sections suivantes.

Pour visualiser les tables créées lors de l'installation de Compiere, entrer l'adresse suiv-
ante dans le navigateur : http://Nom_machine:5500/em. Bien vérier de remplacer
Nom_machine par le nom réel de la machine. Apparaît alors la page de login, il sut
de se connecter en tant que sysdba avec le mot de passe déni lors de l'installation
d'Oracle. Une page d'informations générales sur la base de données apparaît, elle con-
tient notamment une description des sessions actives, de la date de création de la base
de données etc... Il sut alors de cliquer sur l'onglet administration puis sur le lien
Tables et enn sur le bouton exécuter pour voir les diérentes tables présentes.

3.4.2 Eléments de la base de données


Dans cettes sous-section sont analysés certains éléments importants de la base de don-
nées de Compiere.

Vues
Une mesure fondamentale de la protection des données consiste en ceci : les utilisateurs
n'ont accès qu'aux tables ou parties de tables nécessaires à l'accomplissement de leurs
tâches. Dans ce but, des vues sont créees. Dans Compiere un certain nombre de vues
ont été construites.

Syntaxe de création d'une vue : CREATE VIEW nom de la vue AS commande SELECT

Exemple d'une vue de Compiere : AD_Window_vt

CREATE VIEW AS
SELECT
AD_Window_vt

trl.AD_Language, bt.AD_Window_ID, trl.Name, trl.Description, trl.Help, bt.WindowType,

bt.AD_Color_ID, bt.AD_Image_ID

FROM AD_Window bt

INNER JOIN AD_Window_Trl trl ON (bt.AD_Window_ID=trl.AD_Window_ID)

WHERE trl.AD_Window_ID = bt.AD_Window_ID

7 http://www.embarcadero.com/products/erstudio/, dernière visite le 02.11.2005


3.4 Base de données 12

L'eet de cette vue est que seuls les attributs cités dans la clause SELECT pourront
être consultés. Les scripts de création de vue sont disponibles dans : $:\compiere-
all\db\database\Create. Elles peuvent également être consultées graphiquement via le
programme embarcadero, dans le répertoire Main Model.

Tables
La base de données comporte 465 tables pour un total de 7506 colonnes (attributs). En
raison de ce très grand nombre de tables il n'est pas possible d'avoir une bonne vue du
schéma ER entier et des relations entre les tables. C'est pourquoi un modèle logique
a été mis en place, permettant une représentation par module (= fonctionnalités). Il
existe par exemple un module concernant les clients et l'organisation, les paiements, la
gestion des commandes etc.. Cette mise en place du modèle logique facilite énormément
la compréhension globale de la base de données. Il est évident également qu'il permet
de modier (supprimer /ajouter) des tables bien plus aisément que si il n'y avait que
le schéma ER global à disposition.

Figure 3.2: Vue aérienne du schéma de la base de données de Compiere

La Figure 3.2 est une photo 'aérienne' avec un zoom de 4% de la base de données
intégrale. Ceci démontrant ce qui a été cité ci-dessus, à savoir une complexité élevée
à retrouver les éléments (tables, relations etc) et comprendre le fonctionnement de la
base de données. D'où toute l'utilité de décomposer cet ensemble homogène en unités
3.4 Base de données 13

ou modules plus petits. Un module spécique est présenté dans l'Annexe C, an de
comprendre la structure logique formant la base de données Compiere.
14

4 Théorie ORM

4.1 Dénition
ORM (object/relational mapping) est la persistence des objets d'une application orien-
tée objets dans des tables d'une base de données relationnelle. Pour ce faire, un chier
qui décrit le mapping entre les objets et la base de données est employé. Ce chier est
en général écrit en XML (Extensible Markup Language). ORM transforme donc des
données d'une représentation dans une autre.
L'avantage d'ORM, c'est qu'une application interagit avec l'API d'ORM et ce qui
se passe dans les couches inférieures (SQL/JDBC) est masqué.
Une technique traitant l'ORM contient quatre diérentes spécicités :

1. Une API pour eectuer des opérations sur les objets des classes persistantes.

2. Un langage ou API pour spécier des requêtes qui font référence aux classes et

propriétés des classes.

3. Une facilité pour spécier le mapping entre les objets et la base de données.

4. Une technique permettant à l'implémentation ORM d'interagir avec des objets

transactionnels an d'eectuer des fonctions d'optimisation.

ORM peut être implémenté de diverses façons selon Mark Fussel, chercheur dans le
domaine du mapping objet/relationnel.

4.1.1 Purement relationnel


L'application entière est programmée autour du modèle relationnel et toutes les opéra-
tions sont relationnelles et basées sur SQL. Cette solution peut être très intéressante
pour des petites applications comportant peu de code destinées à être réutilisables.
Cependant pour les applications d'une certaine importance cette solution n'est pas op-
timale. La raison en est qu'il devient très compliqué d'étendre l'application car comme
le tout est vu sous formes de tables et relations entre elles, l'ajout de nouvelles tables
signie également un ajout de nouvelles relations entre elles qui sont souvent diciles
à gérer. De plus il faut par la suite adapter tout le code SQL.

4.1.2 Light objet mapping


Les entités sont représentées comme des classes qui sont mappées manuellement vers
les tables du modèle relationnel. Le code SQL/JDBC est masqué grâce à l'emploi de
design patterns. Cette approche est très répandue et est bonne pour des applications
avec un petit nombre d'entités.

4.1.3 Medium object mapping


L'application, contrairement au Pure relational modèle, est modelée autour d'un mod-
èle orienté objets. SQL est généré à un outil de génération de code. L'association entre
4.2 Hibernate 15

les objets est supportée par le mécanisme de persistence et les requêtes peuvent être
réalisées grâce à un langage d'expression orienté objet comme par exemple HQL (Hi-
bernate Query Language). Ce dernier n'est toutefois pas un langage de manipulation
de données comme SQL. Il est utilisé uniquement pour la récupération d'objets et non
pour eectuer des opérations d'insertion, de mise à jour ou de suppresion. Le Medium
object mapping convient bien aux applications de moyenne taille contenant quelques
transactions complexes.

4.1.4 Full object mapping


Ce procédé supporte des procédés complexes propres au monde orienté objet : héritage,
composition, polymorphisme. La couche persistance implémente de la persistance trans-
parente; les classes persistantes n'héritent d'aucune classe de base et ne doivent pas
implémenter d'interface spéciale.

4.2 Hibernate
L'idée initiale était de réaliser le projet grâce à Hibernate. Cependant, Hibernate n'a
pas été utilisé pour réaliser entièrement le projet à cause de problèmes survenus avec
la combinaison de Compiere et d'Hibernate, notamment des problèmes pour la gestion
des triggers. Toutefois des exemples d'utilisation d'Hibernate sur certains modules de
Compiere se trouvent dans la section 5. Une description d'Hibernate, ses buts, son
architecture y sont également présentés car c'est une technologie très puissante et qui
peut être employée pour de multiples tâches. Des explications sur la marche à suivre
pour réaliser le projet terminent la section dédiée à Hibernate.

4.2.1 Présentation
Hibernate est un projet ambitieux dont le but est d'apporter une solution complète au
problème de la gestion des données persistantes. En eet, de quelle utilité serait un
système d'informations dans lequel toutes les données seraient perdues lors de chaque
arrêt du système? Dans une application orientée objet, la persistance permet à un objet
de survivre même si le processus l'ayant créé est détruit. L'état de l'objet en question
peut par exemple être enregistré sur le disque et un nouvel objet avec le même état peut
être recréé dans le futur. Une application Java contient des objets non-persistants et des
objets persistants. Un sous-système est nécessaire pour gérer ces données persistantes.
Le monde objet et le monde relationnel sont très diérents, chacun ayant des avan-
tages et des inconvénients par rapport à l'autre. Comme la représentation des données
dans un système relationnel est fondamentalement diérente du réseau d'objets utilisés
dans une application Java par exemple, beaucoup de tentatives ont été eectuées pour
créer une sorte de pont pour relier ces deux technologies, les faire cohabiter. Hibernate
est justement un de ces projets, considéré à l'heure actuelle comme le plus abouti et le
plus puissant. Hibernate a été lancé vers n 2001 par Gavin King. Ayant eu rapidement
4.2 Hibernate 16

du succès, des développeurs sont à présent aectés à plein temps au développement et


aux améliorations de ce projet Open Source.
Hibernate est un outil de 'mapping' objet/relationnel pour le monde Java. Le terme
mapping objet/relationnel décrit la technique consistant à faire le lien entre la représen-
tation objet des données et sa représentation relationnelle basée sur un schéma de base
de données.
Non seulement Hibernate s'occupe du transfert des classes Java dans les tables de
la base de données, mais il permet de faire des requêtes sur des données an de les
récupérer. Il peut donc réduire de manière signicative le temps de développement qui
aurait été dépensé autrement dans une manipulation manuelle des données via SQL et
JDBC.
Le but principal d'Hibernate est donc de libérer le développeur d'une très grande
partie des tâches de programmation liées à la persistence des données communes, ceci
étant réalisé en automatisant une tâche à priori complexe : persister les objets Java
vers une base de données relationnelle. Eectivement, sans Hibernate, le développeur
devrait écrire lui-même le code permettant de 'mapper' le code objet vers une base de
données. Ce code est souvent complexe, long et coûteux à écrire. Hibernate possède de
plus une architecture exible et grandement congurable : il a été développé dans le
but d'être modulaire, extensible et de permettre aux utilisateurs de pouvoir l'adapter
et le congurer selon leurs besoins.

Figure 4.1: Architecture d'Hibernate


4.2 Hibernate 17

Hibernate est positionné comme une couche entre une application et un système de base
de données. La Figure 4.1 donne un aperçu de l'architecture d'Hibernate. Ce type de
technologie est appelé Framework de mapping objet/relationnel ou de persistance objet
des données.
En eet, la couche applicative voit les données comme des classes dont le contenu
reste en mémoire même après la n d'exécution du programme, d'où persistance objet
des données.
De plus, le lien entre les classes exposées et la source physique des données (souvent
une base de données relationnelle) est dénie par un chier xml, d'où mapping objet-
relationnel.

4.2.2 Avantages d'Hibernate


Hibernate comporte de nombreux avantages par rapport à une application réalisée
classiquement à l'aide de JDBC. Une application Hibernate est très facilement et rapi-
dement congurable pour fonctionner avec un tout autre type de base de données que
celui utilisé actuellement par cette dernière. Il sut de modier quelques lignes dans
le chier de conguration comme il sera montré dans la section suivante. Hibernate
permet donc d'éviter une dépendance d'un logiciel avec un certain type de base de
données.
Un des avantages clés d'Hibernate est le caching. Son fonctionnement est analogue
aux mémoires caches qui équipent les processeurs des ordinateurs personnels actuels. A
chaque fois qu'un objet est employé par Hibernate, ce dernier est placé dans un cache,
ce qui a pour eet de recharger un objet très rapidement lors d'une utilisation future.
La gestion du cache implémentée pour Hibernate est très compliquée, ce dernier doit
optimiser l'emploi du cache (ce dernier ayant une taille en mémoire limitée) en essayant
d'y garder les objets les plus souvent référencés.
Les gains de performances sont grandement améliorées grâce à l'emploi d'une mé-
moire cache.
Hibernate dispose également d'une fonction 'lazy initialisation'. Elle permet de
charger les états de divers objets depuis la base de données seulement lorsque l'application
les utilise. Des gains de performance sont également réalisés car l'application initialise
simplement les objets qu'elle utilise et non tous les objets.

4.2.3 Hibernate : les complications


Les triggers sont souvent dicilement combinables avec les outils ORM. Il est problé-
matique de synchroniser les eets d'un trigger avec la représentation en mémoire des
données. Le problème est qu'Hibernate se situe dans une couche au-dessus de la base
de données qui comprend une table avec son trigger associé. Supposons qu' Hibernate
enregistre un nouvel élément dans une table sur laquelle est appliquée un trigger. Hi-
bernate ne connaîtra pas le résultat qu'aura l'application du trigger sur l'enregistrement
(car le trigger est eectué après l'enregistrement de l'objet par Hibernate).
4.2 Hibernate 18

Ce genre de problème peut être contourné en employant une fonction qui force le
trigger a s'exécuter immédiatement (au niveau d'Hibernate) et éventuellement avec une
fonction 'refresh' pour connaître le résultat du trigger
19

5 Utilisation d'Hibernate

Le but du projet était de créer une interface entre Compiere et une base de données.
Cette dernière, se résumant aux seuls nom d'Oracle et de Sysbase, devait alors pouvoir
être de tout type. C'est à dire que Compiere devrait pouvoir non plus simplement
accepter une base de données de type Oracle ou Sysbase mais également n'importe quel
système de base de données et également des bases de données objets.
Après les deux premières étapes réalisées (manuel d'installation Compiere + étude
code source, base de données), la troisième étape a été revue. Eectivement, réaliser
l'idée initiale représente un projet bien plus complexe qu'on aurait pu penser, en partie
de part la complexité et la taille du code source de Compiere. Je pense notamment à la
base de données (environ 450 tables) et toutes les relations complexes qu'il y a entre les
tables. L'emploi de trigger devient également problématique avec l'emploi d'Hibernate.
Pour cette troisième partie, je vais donc adopter un point de vue beaucoup plus
général en parlant de la manière dont il faudrait s'y prendre pour réaliser l'idée initiale.

Pour ce faire, toutes les étapes à eectuer an de pouvoir utiliser Hibernate sont décrites
et analysées à l'aide d'un exemple. Eclipse est employé comme éditeur pour réaliser tous
les exemples. L'installation d'Hibernate est la première étape à réaliser. La seconde
étape consiste à choisir une base de données spécique pour interagir avec Hibernate.
La conguration ainsi que les divers chiers / classes à écrire pour un projet Hibernate
représentent la 3ème étape.

5.1 Installation d'Hibernate


La première action à eectuer est d'installer le plugin Hibernate Synchronizer pour
Eclipse. Ce plugin est très utile car il permet d'employer Hibernate directement dans
Eclipse et beaucoup de tâches, comme par exemple les chiers de conguration et map-
ping sont automatisés. Eectivement, après l'installation du plugin on peut directement
créer des chiers de type Hibernate Conguration File ou Hibernate Mapping File (Dans
Eclipse : Fichier->new->other->Hibernate File).

5.1.1 Installation du plugin


• Dans Eclipse, cliquer sur "Help > Software Updates > Find and Install"

• Sélectionnez "Search for new features to install"

• Cliquer sur "New Remote Site" et entrer l'URL suivante : "http://www.binamics.


com/hibernatesync. Donner comme nom au site "Hibernate Sync".

• Cochez "Synchronizer"

• Continuer le proocessus d'installation en cliquant sur next puis accepter toutes les
demandes
5.2 Installation de la base de données 20

Hibernate synchronizer est à présent intallé. Il est temps à présent de télécharger


Hibernate8 version 2.1.8 (version utilisée pour le projet) et Hibernate-extensions 2.1.3
qui contiennent les chiers .jar nécessaires.
Créer un nouveau projet dans Eclipse, dans mon cas je l'appelle Last. A partir de
l'explorateur windows, créer un répertoire /lib à la racine du projet. Ce répertoire va
contenir les diérents chiers sous forme de .jar nécessaires au bon fonctionnement de
l'aplication. Dans ce répertoire /lib, copier :

• hibernate2.jar, cglib-full-2.0.2.jar, commons-collections-2.1.1.jar, commons-logging-


1.0.4.jar, dom4j-1.4.jar, ehcache-0.9.jar, jta.jar, odmg-3.0.jar (archive Hibernate-
2.1.8.zip)

A ce stade, un projet contenant un répertoire \lib est donc créer. Le dossier \lib contient
les .jar nécessaires. Il faut également inclure dans ce dossier l'archive jar correspondant
à la base de données, processus qui est décrit au point 2.2 ci-dessous.

5.2 Installation de la base de données


Les développeurs d'Hibernate assurent un support ociel pour les SGBDR (Système
de gestion de base de données relationnelles) les plus connus : Oracle, MySQL, Post-
greSQL, etc.. Rappelons que Compiere ne fonctionne qu'avec Oracle et que le but du
projet est de démontrer que les objets créés par Compiere peuvent être enregistrés dans
une base de données autre que Oracle. Pour ce faire, j'ai choisi d'installer et d'employer
Hsqldb qui est un SGBDR relationnel écrit en Java et disponible sous la forme d'une
simple archive JAR (Java ARchive) à intégrer au projet.

5.2.1 Installation de Hsqldb


Télécharger Hsqldb9 et copier hsqldb.jar dans le dossier lib du projet. Hsqldb peut fonc-
tionner en plusieurs modes: mode serveur, mode 'stand-alone' et mode 'en mémoire'.
Le mode serveur est la manière la plus ecace et rapide, c'est le mode employé dans
mon exemple. Il s'agit de démarrer un serveur puis de s'y connecter. Il est intéressant
de noter que hsqldb.jar contient le pilote JDBC qui peut être utilisé avec toute autre
application compatible JDBC pour manipuler une base de données Hsqldb.

Démarrage du serveur :
Ouvrir une console et eectuer depuis le répertoire du projet :

• java -cp lib\hsqldb.jar org.hsqldb.Server -database.0 mydb -dbname.0 xdb .

8 http://hibernate.org/ , dernière visite le 05.11.2005


9 http://hsqldb.org/ , dernière visite le 10.11.2005
5.2 Installation de la base de données 21

Cette commande a pour eet de lancer le serveur avec une base de données dont les
chiers de congurations sont de type mydb, xdb étant l'alias permettant de s'y con-
necter.

Connexion au serveur et création de tables :


Ouvrir une nouvelle console en prenant bien soin de laisser la première console continuer
de s'exécuter. Depuis le répertoire du projet, exécuter :

• java -cp lib\hsqldb.jar org.hsqldb.util.DatabaseManager

Figure 5.1: HSQL Database Manager login

La Figure 5.1 montre la fenêtre de paramètres de connexion qui apparaît après


l'exécution de la commande ci-dessus. Les cinq champs qui nous intéressent pour
l'instant sont Type, Driver, URL, User et Password.

Type : sélectionner l'option HSQL Database Engine Server

Driver : org.hsqldb.jdbcDriver

URL : jdbc:hsqldb:hsql://localhost/xdb.

User : comme aucun utilisateurs n'a été crée, il faut se connecter avec le User sa (system
administrator)
5.2 Installation de la base de données 22

Password : il n'y a pas de mot de passe associé à l'utilisateur sa, laisser donc ce champ
vide

Figure 5.2: HSQL Database Manager

Cliquer ensuite sur Ok, qui aura pour eet de faire apapraître le HSQL Database
Manager Le Database Manager permet de gérer la base de données. Les requêtes
doivent être insérées dans le champ entre le bouton Clear et le bouton Execute. C'est
dans le Database Manager qu'on peut créer des utilisateurs, des nouvelles tables, gérer
des comptes et eectuer toutes sortes d'opérations.
Dans mon exemple, la base de données est formée par une table nommée personnes
et contenant les attributs suivants : id, nom, prenom, age. Il s'agit donc en premier
lieu de créer cette table. Pour ce faire, il faut copier le script ci-dessous dans la fenêtre
d'exécution du Database Manager et cliquer sur Execute, comme indiqué à la Figure
5.2 .
CREATE TABLE Personnes(
Id INTEGER ,
nom VARCHAR(30),
prenom VARCHAR(30),
age INTEGER) ;
5.3 Fichiers à réaliser pour employer Hibernate 23

A présent une table vide nommée Personnes est créee. Eectuer la commande suiv-
ante : SELECT * FROM Personnes

Si la création de la table a bien fonctionné, cette commande devrait faire apparaître


les attributs Id, nom, prenom, age sur une ligne dans l'espace blanc au-dessous de la
fenêtre d'exécution.
Notre but est à présent d'insérer des tuples dans cette table en employant Hibernate.
Un tuple sera crée dans un monde 'objet' grâce à une commande du type : new Per-
sonnes(1,Schorderet,Thibaut, 24). Le travail d'Hibernate sera alors de transformer
la représentation objet obtenue en une représentation tabulaire, c'est à dire mapper
l'objet dans les diérentes colonnes de la table Personnes. Les diérentes opérations à
réaliser pour arriver à ce but sont décrites dans les sections suivantes.

5.3 Fichiers à réaliser pour employer Hibernate


Pour l'instant la base de données est prête et un projet a déjà été créé dans Eclipse
avec un sous-répertoire \lib à la racine du projet contenant tous les .jar nécessaires.
A présent il faut ajouter au classpath du projet toutes les librairies du dossier \lib.
Pour ce faire, clique droit sur le nom du projet ('Last' pour le projet) et properties.
Cliquer alors sur Java build path puis sur l'onglet Librairies. Sélectionner tous les jars
du dossiers \lib et cliquer sur ok.

5.3.1 Fichier de conguration d'Hibernate


Hibernate est conguré diéremment selon qu'il est utilisé dans un environnement non
géré (non-managed environment) ou dans un environnement géré (managed environ-
ment).

Environnement non géré


Un environnement non géré fournit des éléments de gestion très limités. Un tel envi-
ronnement ne fournit pas une gestion des ressources automatique, ni une infrastructure
de sécurité. Par exemple, l'application doit elle-même gérer les connexions à la base
de données. Un container de servlet comme Tomcat fournit un environnement serveur
non géré pour les applications web Java.
Comme on l'a vu, dans un environnement non géré, l'application est responsable
d'obtenir les connections JDBC. Hibernate, faisant partie de l'application, est respons-
able pour l'obtention de ces connections. Il est nécessaire de dire à Hibernate comment
acquérir (créer) ces connections JDBC. En général il n'est pas conseillé et optimisé de
créer une nouvelle connection à chaque fois que l'application doit communiquer avec
la base de données. Au contraire les applications Java devraient employer un pool de
connexions JDBC. Un pool de connexions est un mécanisme permettant de réutiliser les
5.3 Fichiers à réaliser pour employer Hibernate 24

connexions créées. En eet, la création systématique de nouvelles instances de Connec-


tion peut parfois devenir très lourde en consommation de ressources. Pour y remédier,
un pool de connexions ne ferme pas les connexions lors de l'appel à la méthode close().
Au lieu de fermer directement la connexion, celle-ci est "retournée" au pool et peut
être utilisée ultérieurement.
La gestion du pool se fait en général de manière transparente pour l'utilisateur.

Figure 5.3: Environnement non géré

La Figure 5.3 montre un pool de connexions dans un environnement non géré sans
l'emloi d'Hibernate, typiquement une application web. Comme cet environnement n'est
pas géré, l'application doit implémenter son propre algorithme de pooling ou alors
faire appel à une librairie pour s'occuper du pool. Tout ce travail est eectué par
le programmeur de l'application et le code nécessaire est souvent compliqué et long à
programmer. Sans Hibernate, une application appelle généralement le pool pour obtenir
une connexion et exécuter les requêtes SQL.

Figure 5.4: Environnement non géré avec Hibernate

Hibernate apporte de la simplication, ce dernier agissant comme un client du pool


de connexion JDBC, comme on peut le voir à la Figure 5.4. L'application emploie les
API de Session et Query pour eectuer des opérations persistantes et n'a à gérer que
5.3 Fichiers à réaliser pour employer Hibernate 25

des transactions avec la base de données, par exemple en employant l'API Transaction
d'Hibernate.
Hibernate congure tout seul le connexion pool, il sut simplement de lui décrire
les propriétés désirées dans un chier spécial, appelé hibernate.properties. Si le chier
de conguration est au format xml, comme dans mon exemple, le chier sera appelé
hibernate.cfg.xml. Ce chier XML, à la diérence du chier hibernate.properties qui
contient uniquement des paramètres de conguration, spécie également la location des
chiers de mappings. La syntaxe ainsi que la création d'un tel chier est décrite plus
loin dans cette section.

Environnement géré
Un environnement géré traite automatiquement certains aspects comme la sécurité
d'une application (authorisation et authentication), le pool de connexions et la ges-
tion des transactions. Les serveurs d'applications J2EE sont typiquement des serveurs
fournissant un environnement géré.

Création du chier de conguration


Clique droit sur le dossier src du projet et choisir new->other->HIbernate->Hibernate
Conguration File.

Une interface pareille à la Figure 5.5 apparaît. Database Type : HypersonicSQL (type
pour Hsqldb)
Application Server : N/A
Driver Class :
Database URL :
Username : sa
Password :

Cliquer sur Finish qui a pour eet de créer le chier hibernate.cfg.xml qui est le chier
de conguration d'Hibernate. Cependant ce chier nécessite quelques modications car
le chier généré est destiné à être utilisé sur un serveur d'applications. Les modications
à eectuer sont décrites ci-après dans le code généré.

Structure typique d'un chier de conguration


<hibernate-conguration>
<session-factory>
<! local connection properties >
<property name="nom"> Paramètres </property>
<mapping resource="chier.hbm" />
</session-factory>
</hibernate-conguration>
5.3 Fichiers à réaliser pour employer Hibernate 26

Figure 5.5: Interface de création du chier de conguration

Tout chier de conguration au format xml commence par la balise <hibernate-


conguration>. Si le chier de conguration n'est pas en xml, et est donc un chier
.properties, il n'y pas de syntaxe spécique à respecter, les déclarations des diérents
paramètres de conguration sont simplement spéciés à la suite.
La balise <session-factory> est également obligatoire et se place juste après la balise
<hibernate-conguration>. Une balise de type <! commentaires > sert à insérer des
commentaires. Les balises <property name="nom"> dénissent des éléments à cong-
urer comme par exemple l'URL de la connexion à la base de données ou le mot de passe
utilisateur. Le nombre de ces balises peut être relativement important suivant le degré
de précision voulu dans la conguration. Eectivement, des éléments qui n'auraient
pas été dénis dans le chier de conguration prennent une valeur par défaut lors de
l'exécution de l'application.
La balise <mapping resource="chier.hbm" /> dénit le chemin d'accès au chier
.hbm qui contient une description du schéma de la base de données avec lequel va
5.3 Fichiers à réaliser pour employer Hibernate 27

interagir l'application. Ces chiers seront décrits dans la section suivante.


Remarque : si le chier de conguration est du type chier.properties, il est nécessaire
de spécier à l'application le chemin d'accès à ce chier pour qu'elle puisse le charger
au démarrage. Au contraire, si le chier de conguration est du type hibernate.cfg.xml,
Hibernate va automatiquement chercher un chier avec ce nom dans le classpath lors
de l'appel de la fonction congure() qui doit obligatoirement être appelée pendant
l'initialisation d'Hibernate. Il est possible d'utiliser un autre nom de chier à la place
de hibernate.cfg.xml, par exemple mycong.cfg.xml. Ce chier peut également être mis
dans un répertoire, par exemple hibernate-cong. Dans ce cas, il faut passer le chemin
d'accès en argument de la fonction congure(), qui donnerait ici : congure(/hibernate-
cong/mycong.cfg.xml).

Fichier de conguration de l'exemple


<hibernate-conguration>
<session-factory>
<! local connection properties >
<property name="hibernate.connection.url"> jdbc:hsqldb:hsql://localhost/xdb </property>
<property name="hibernate.connection.driver_class"> org.hsqldb.jdbcDriver </property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password" />
<property name="dialect"> net.sf.hibernate.dialect.HSQLDialect </property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.use_outer_join">true</property>

<!MODIFICATIONS>
<!
<property name="hibernate.transaction.factory_class">
net.sf.hibernate.transaction.JTATransactionFactory </property>
<property name="jta.UserTransaction"> java:comp/UserTransaction </property>
//>
<!FIN MODIFICATIONS>

<!A AJOUTER>
<property name="hibernate.transaction.factory_class">
net.sf.hibernate.transaction.JDBCTransactionFactory </property>
<!FIN AJOUT>
<mapping resource="Personnes.hbm" />
</session-factory>
</hibernate-conguration>

Ci-dessous sont décrits en détails les diérents éléments du chier de conguration.


Cependant il faut bien savoir que même si ce chier a été généré automatiquement, ses
caractéristiques ayant été spéciées par le programmeur via les interfaces d'Eclipse, il est
utile de le comprendre pour d'éventuelles modications manuelles. D'ailleurs le chier
généré doit subire quelques modications. Il faut mettre en commentaires les éléments
5.3 Fichiers à réaliser pour employer Hibernate 28

se trouvant entre les balises <!MODIFICATIONS> et <!--FIN MODIFICATIONS> et


ajouter les deux lignes entre les balises <!A AJOUTER> et <!FIN AJOUT>.

• <property name="hibernate.connection.url"> : spécie l'URL du serveur de la


base de données. Dans l'exemple, l'url est jdbc:hsqldb:hsql://localhost/xdb.

• <property name="hibernate.connection.driver_class"> : spécie le driver util-


isé pour la connexion à la base de données. Comme Hsqldb est employé dans
l'exemple, le driver est contenu dans hsqldb.jar et se nomme org.hsqldb.jdbcDriver.

• <property name="hibernate.connection.username"> : spécie le nom d'utilisateur


qui pourra se connecter. Ici, sa pour system administrator.

• <property name="hibernate.connection.password" /> : spécie le mot de passe


si il y en a un, vide dans ce cas.

• <property name="dialect"> : chaque système de base de données possède son


propre dialecte. Un dialecte est une classe dont le rôle est de traduire les ordres
SQL dans le langage propre à chaque SGBDR car certaines diérences peuvent
exister. Dans l'exemple, comme c'est Hsqldb qui est utilisé, le dialecte à spécier
est : net.sf.hibernate.dialect.HSQLDialect.

• <mapping resource="Personnes.hbm" /> : spécie le chier de mapping à utiliser.


Dans notre cas, Personnes.hbm car la table en question dans la base de données
s'appelle Personnes.

Après en avoir terminé avec le chier de conguration qui est un élément fondamental
pour le bon fonctionnement d'Hibernate et notamment qui contient les paramètres
nécessaires pour se connecter à la base de données, il est nécessaire d'avoir un chier
contenant une description de la base de données qui travaille avec l'application. Un tel
chier est appelé un document de mapping objet/relationnel.

5.3.2 Document de mapping objet / relationnel


Il s'agit d'un chier XML dans lequel sont décrites les associations entre les membres
d'une classe Java et les colonnes d'une table de la base de données. Un tel chier
est nécessaire an d'indiquer à Hibernate comment faire en sorte qu'une classe soit
persistante. Un tel chier comporte l'extension hbm qui signie Hibernate Mapping.

Création du document de mapping objet / relationnel


Avant de créer ce chier de mapping, il faut créer un package à partir du sous-
répertoire src du projet. Ceci aura pour eet que les chiers générées automatiquement
seront dans des packages diérents selon leur fonctionnalité. Dans l'exemple, le package
est appelé com.minosis.hibernate. Par la suite, après la création des chiers, on trouve
par exemple le package com.minosis.hibernate.dao qui contient le chier de congura-
tion et le chier de mapping. Le package com.minosis.hibernate.java contient tous les
5.3 Fichiers à réaliser pour employer Hibernate 29

chiers crées par le programmeur avec l'extension .java, comme par exemple Test.java.
Une fois cette opération accomplie, le chier .hbm peut être créé :
Clique droit sur le dossier src du projet et choisir new->other->Hibernate->Hibernate
Mapping File.
Une fenêtre apparaît et contient par défaut certains des paramètres dénis dans le
chier de conguration. Il sut d'ajouter le mot de passe de l'utilisateur. A noter
que le mot de passe de l'utilisateur system administrator est vide. Cliquer sur refresh,
ce qui aura pour eet de faire apparaître le nom des tables de la base de données. Il
faut bien sûr que le serveur de la base de données ainsi que la base de données elle-
même soit toujours en cours d'exécution. Sélectionner toutes les tables qui ont été
trouvées et cliquer sur nish. Tous les derniers chiers nécessaires à Hibernate seront
crées. Un chier particulièrement intéressant est BasePersonnes.java du package
com.minosis.hibernate.base. Il contient des données relatives à la table Personnes.
Evidemment, le chier Personnes.hbm a également été crée et se trouve dans le package
com.minosis.hibernate.dao. Son contenu est décrit ci-dessous et comme nous le
verrons, il nécessite quelques modications.

Structure d'un chier hbm


Ci-dessous, un exemple simple d'un chier hbm, appelé aussi généralement un document
XML de mapping. Les numéros en exposant à la n de certaines lignes font référence
aux numéros entre parenthèses situés à la n de l'exemple de chier de mapping et
contiennent des descriptions détaillées sur le rôle et le fonctionnement des balises mises
en gras.

<?xml version="1.0" encoding="ISO-8859-1"?>


<!DOCTYPE hibernate-mapping SYSTEM
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>1
2
<class name="Personnes" table="personne">

<meta attribute="class-description">3
Cette classe représente les caractéristiques d'une personne
</meta>

<idname="id" type="int">4
<column name="id" sql-type="int(4)"/>5
6
<meta attribute="scope-set">protected</meta>
7
<generator class="native" />
</id>

<property name="nom" type="string" not-null="true">8


<column name="nom" sql-type="char(50)" not-null="true"/>
<meta attribute="eld-description">
5.3 Fichiers à réaliser pour employer Hibernate 30

Champ contenant le nom d'une personne


</meta>
</property>

</class>
</hibernate-mapping>

Un document hbm peut contenir un nombre indéterminé de déclarations de classes et


possède la syntaxe classique de tout document XML.

(1) Toutes les déclarations et descriptions de la base de données sont comprises entre les
balises <hibernate-mapping package = ...> et </hibernate-mapping>, package étant
utilisé pour indiquer que toutes les classes déclarées appartiennent au même package
Java. Pour mélanger des paquets, il sut d'omettre l'attribut package, et de donner à
chaque classe son nom complet.

(2) La déclaration d'une classe est réalisée à l'aide de l'élément <class /> auquel est
passé en attribut son nom et sa table dans le SGBDR. Dans notre exemple : nom =
Personnes et table = personne.

(3) L'élément <meta /> permet de documenter un chier hbm. L'élément attibute de
meta permet de spécier la description faite. Dans l'exemple ci-dessus, l'attribut eld-
description est employé pour une description d'un champ et l'attribut classe-description
pour des commentaires sur la classe. Les données inscrites dans ces éléments sont
également ajoutées au code source Java généré à partir de ce chier. Un élément
<meta /> contient donc le commentaire JavaDoc qui sera inséré devant la déclaration
de la classe Java.

(4) L'élément id sert à indiquer la clé primaire de la table. Type dénit la nature des
éléments de cette colonne, dans ce cas le type est déclaré int (integer). Tous les types
classiques peuvent être employés (int, string, long...). L'attribut column contient le
nom de la colonne de la table, id dans l'exemple.

(5) Column name contient le nom de la colonne de la table en question dans la base de
données.

(6) Le contenu de <id /> présente une nouvelle utilisation intéressante de <meta />.
Le type scop-set sert à indoquer la portée du mutateur, setId(), dans le code Java.
Comme il est impensable de le laisser public, qui est la portée par défaut, la manière
dont elle est calculée est ici changée.

(7) Le générateur natif est celui du SGBDR utilisé. Il est néanmoins possible de créer
son propre générateur avec l'API Hibernate. On peut, par exemple générer des clés en
fonction de la date.
5.3 Fichiers à réaliser pour employer Hibernate 31

(8) Les éléments property dénissent une propriété se réferrant à une colonne de la
table.
Le chier généré automatiquement par Hibernate n'est pas conforme à la DTD,
hibernate-mapping-2.0.dtd. Il risque d'y avoir des erreurs lorsque ce dernier sera parsé.
C'est pour ça qu'il faut le remplacer par le chier ci-dessous, totalement conforme quant
à lui.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
<class name="com.minosis.hibernate.Personnes" table="Personnes">

<id name="Id" type="integer">


<column name="id" sql-type="int(4)"/>
<generator class="increment" />
</id>

<property name="Nom" type="string">


<column name="nom" sql-type="char(50)" not-null="true"/>
</property>

<property name="Prenom" type="string">


<column name="prenom" sql-type="char(50)" not-null="true"/>
</property>

<property name="Age" type="integer">


<column name="age" sql-type="int(4)" not-null="true"/>
</property>

</class>
</hibernate-mapping>

Ce chier décrit les attributs de la table Personnes créée à l'aide d'Hsqldb. Ce chier
peut être interprété de la manière suivante : chaque enregistrement qui sera inséré dans
la table comportera un numéro d'identication, un nom, un prénom et un âge. Ce chier
est très important car grâce à lui, l'application sait comment réaliser le mapping.

5.3.3 Gestion de la persistance


A ce stade, Hibernate et le Hsqldb sont congurés. Il faut à présent écrire le code Java
exploitant les mappings dénis.
5.3 Fichiers à réaliser pour employer Hibernate 32

Il existe 5 interfaces principales qui sont utilisées dans chaque application Hibernate.
C'est en employant ces interfaces qu'on peut enregistrer puis récupérer des objets per-
sistants ainsi que contrôler les transactions. Il est dès lors utile de décrire brièvement
le rôle de chacune de ces interfaces an de comprendre le code de la classe Tested.java,
présenté ci-après.

Figure 5.6: API d'Hibernate dans une architecture en couches

La Figure 5.6 illustre le rôle des plus importantes interfaces d'Hibernate dans la
couche business et la couche de persistance. Ces interfaces peuvent être classiées de
la sorte :

• Interfaces appelées par l'application pour eectuer des opérations basiques de


création, lecture, mise à jour et suppression. Ces opérations sont généralement
désignées sous le terme CRUD (create, read, update, delete). Appartiennent à
cette classe d'interface, les interfaces Session, Transaction et Query.

• Les interfaces appelées par le code d'infrastructure de l'application pour congurer


Hibernate, la plus importante étant la classe Conguration.

• Des interfaces qui permettent des extensions des fonctionnalités de mapping


d'Hibernate comme par exemple UseType.
5.3 Fichiers à réaliser pour employer Hibernate 33

• Des interfaces dites de callback qui permettent à l'application de réagir à des


événements qui se déroulent dans Hibernate.

Les 5 interfaces principales :


1. Session interface
L'interface session est l'interface primaire utilisée par les applications Hibernate. Une
instance de Session est légère et peu coûteuse à créer ce qui est très important car une
application devra créer et détruire des sessions très souvent, éventuellement à chaque
requête. Les sessions Hibernate doivent être utilisées par un seul thread à la fois.

Dans Hibernate une session est quelque chose entre une connexion et une transaction
pouvant être vu comme un cache ou une collection d'objets chargés en relation avec une
unité de travail. Hibernate peut détecter des changements sur ces objets. Une session
est parfois appelée un manager de persistance parce que c'est également l'interface pour
des opérations relatives à la persistance, comme par exemple enregistrer ou récupérer
des objets.

2. SessionFactory interface
Une application obtient des instances Session de la part de SessionFactory qui quant à
lui n'est pas du tout léger. Un SessionFactory est destiné à être partager par des threads
de plusieurs applications. Typiquement, on trouve un SessionFactory pour l'application
entière, crée par exemple durant la phase d'initialisation de l'application. Cependant si
une application utilise plusieurs base de données en utilisant Hibernate, un SessionFac-
tory sera nécessaire pour chaque base de données. Le cache de SessionFactory génére
des requêtes SQL et d'autre métadonnées de mapping qu'Hibernate utilise pendant
l'exécution. Il maintient aussi dans le cache des données qui ont été lues et qui peuvent
éventuellement être réutilisées dans le futur, ceci pour optimiser les performances.

3. Conguration interface
Un objet conguration est utilisé pour congurer Hibernate et pour le démarrer.

L'application utilise une instance de Conguration an de spécier la localisation du


chier de mapping (chier HBM) et les propriétés spéciques d'Hibernate. L'instance
de Conguration crée alors SessionFactory à l'aide de la méthode buildSessionFactory().

4. Transaction interface
5.3 Fichiers à réaliser pour employer Hibernate 34

Cette interface est une API optionnelle. Les applications Hibernate peuvent choisir
d'employer ou non cette interface. Dans le cas où cette interface n'est pas employée,
les applications doivent gérer elles même les transactions. Dans le monde des bases
de données, la notion d'unité de travail est appelée et implémentée comme étant une
transaction de base de données.

Une transaction peut se terminer de deux façons : elle peut être commited ou rolled back
. Par conséquent, les transactions des bases de données sont atomiques. Une transaction
commited est une transaction qui a été eectuée et enregistrée. Un rolled back sur une
transaction est eectué lors d'un problème rencontré au cours de l'exécution de la
transaction.

5. Query interface
L'interface Query permet d'eectuer des requêtes sur la base de données et de contrôler
comment sont exécutées ces requêtes. Ces dernières sont écrites en HQL ou en dialect
natif de la base de données. Une instance de Query est utilisée pour relier les paramètres
de la requête limiter le nombre de résultats retournés par la requête et nalement pour
exécuter la requête. Une instance Query est légère et ne peut pas être employée en
dehors de la session qui l'a créée.

5.3.4 Création du chier Tested.java


Il y a des étapes d'initialisation à eectuer qu'on retrouve dans chaque chier Hibernate.
Ces étapes sont les suivantes :

1. Créer une instance de Conguration : Conguration cfg = new Conguration();

2. Créer une sessionFactory a partir de l'instance de Conguration : SessionFactory

sessions = cfg.buildSessionFactory();

3. Créer et ouvrir une session Session session = sessions.openSession();

4. Créer une transaction qui contiendra les opérations à eectuer : Transaction tx


= session.beginTransaction(); Pour que la transactin en question soit eectuer, il
faut la terminer par tx.commit(); Un tx.rollback() aura pour eet de l'annuler.

Le chier Tested.java va contenir le code avec une synataxe propre à Hibernate. C'est
ce chier qui va créer des instances de Personnes et va se charger de les enregistrer
dans la table Personnes. Pour le créer, clic droit sur le dossier src du projet et choisir
new->File, puis y écrire le code ci-dessous.
5.3 Fichiers à réaliser pour employer Hibernate 35

Ce code eectue une opération similaire aux deux requêtes suivantes :

insert into Personnes (Nom, Prenom, Age)


values ('Schorderet', 'Thibaut', 44)

insert into Personnes (Nom, Prenom, Age)


values ('Egger', 'Julie', 27)

La clé primaire Id est ajoutée et incrémentée automatiquement à chaque nouvel


enregistrement.
5.3 Fichiers à réaliser pour employer Hibernate 36

Explication du code :
• SessionFactory sessions = new Conguration().congure().buildSessionFactory();

Crée une sessionFactory a partir d'une instance de conguration. Lorsque la fonction


congure() est appelée, Hibernate cherche un chier nommé Hibernate.cfg.xml (chier
crée à la section 2.3.1) dans le classpath.

• Session session =sessions.openSession();

Ouverture d'une session à l'aide de la sessionFactory créée.

• Transaction tx = session.beginTransaction();

Ouverture d'une transaction à l'intérieur de la session précédemment créée.

• Personnes contact = new Personnes();

Création d'une instance de type Personnes, dont le constructeur a comme argu-


ment les noms de colonne de la table correspondante dans la base de données.

• contact.setNom("Schorderet");

Aectation d'une valeur au champ Nom.

• contact.setPrenom("Thibaut");

Aectation d'une valeur au champ Prénom.

• contact.setAge(new Integer(44));

Aectation d'une valeur au champ Age.

• session.save(contact);

Sauvegarde du tuple.

• tx.commit();

Insère les tuples sauvés dans la base de données.

• session.close();

Fermeture de la session. Il est nécessaire d'en ouvrir à nouveau une pour une
prochaine transaction.
On peut à présent se rendre compte que les enregistrements ont été insérés dans
la base de données en eectuant : SELECT * FROM Personnes dans le Hsqldb Database
Manager de la base de données précédemment créée.
5.3 Fichiers à réaliser pour employer Hibernate 37

Le code qui vien d'être présenté insère des enregistrements dans la base de données.
Le code ci-dessous récupère des enregistrements selon des conditions dans la base de
données puis peut par la suite les modier ou eectuer toutes sortes d'opérations.

Explication du code :
• Personnes contact = (Personnes) session.load(Personnes.class, new Integer(6));

Récupère la personne qui a un Id valant 6.

• contact.setPrenom("Jacques");

Mise à jour du prénom de la personne qui a un Id valant 6. Dans ce cas la valeur


du prénom aectée à cette personne est Jacques .

• session.save(contact);

Sauvegarde des changements.


5.4 Exemple de mapping pour Compiere 38

Evidemment ces exemples ne montrent pas toute la puissance d'Hibernate. Ils permet-
tent toutefois une bonne introduction et contiennent les éléments principaux à maîtriser
pour aller éventuellement plus en profondeur. Le site ociel d'Hibernate10 contient
la documentation nécessaire pour approfondir ses connaissances ainsi qu'une Api en
Javadoc contenant tous les packages d'Hibernate.

5.4 Exemple de mapping pour Compiere


Dans cette section, c'est un objet de Compiere qui va être mappé dans la base de
données Hsqldb. Ayant pris connaissance des étapes à eectuer pour travailler avec
Hibernate dans la section précédente, la marche à suivre pour la présentation de cette
solution va suivre le même schéma, c'est à dire :

1. Création de la table dans laquelle va être mappé l'objet

2. Création du chier de conguration d'Hibernate

3. Création du document de mapping objet / relationnel

4. Création des chiers de manipulation

Les détails des manipulations à eectuer pour créer chaque chier ne sont pas décrits
(voir section 5.3 pour explications). Le contenu de ces chiers est présenté, une fois
qu'ils ont été générés.

Figure 5.7: Enregistrement de l'objet dans la table 1

La Figure 5.7 montre graphiquement le but à réaliser pour cet exemple, à savoir
mapper cet objet dans une table d'une base de données relationnelle.
Bien que cet exemple est réalisé avec une seule table, il permet de comprendre l'idée
et le processus à eectuer pour travailler sur le projet Compiere en entier. Les solutions
sont présentées sous forme de code dans la documentation car il n'est pas possible de
l'implémenter pour l'instant en raison de toutes les dépendances entre les classes et
à l'intérieur des classes. En s'occupant d'une fonctionnalité précise comme dans cet
exemple, le programme ne peut même pas être compiler, trop d'erreurs sont générées.
Eectivement il faudrait migrer le programme complet vers Hibernate. C'est donc une
10 http://www.hibernate.org, dernière visite le 05.11.2005
5.4 Exemple de mapping pour Compiere 39

sorte de tutorial pour un éventuel développement futur de Compiere ou un autre projet


avec la technologie Hibernate qui est décrit.

1. Création de la table
Pour cet exemple, les données devront être enregistrées dans la table M_Product
_Costing qui est une table créée dans Oracle lors de l'installation de Compiere. Il s'agit
donc d'avoir la table M_Product_costing avec tous ses attributs dans Hsqldb. C'est
dans cette table précisément que Hibernate devra sauver l'objet.

Cette table contient à l'origine déjà quelques enregistrements : on peut s'en rendre
compte en ouvrant cette table directement dans Oracle.

Dans Embarcadero ER/Studio, on retrouve cette table sous forme graphique dans le
répertoire modèle logique. Le chier java qui contient les informations d'insertion dans
cette table se nomme ProductInfo.java et se trouve dans le package serverRoot.src.main.
server.org.compiere.acct. Ce n'est pas le seul chier qui traite cette table, mais c'est
celui-ci qui est employé dans l'exemple.

C'est cette approche qu'il faut avoir pour intégrer Hibernate dans Compiere. C'est-
à-dire qu'il faut en premier lieu connaître la structure de la base de données (tables,
attributs) qui va enregistrer les éléments. Une fois cette étape réalisée, il faut repérer
dans le code les instructions qui traitent avec des tables, plus précisément les instruc-
tions d'insertion dans des tables. Bien sûr que pour une intégration complète de Com-
piere et Hibernate, les instructions de récupération d'enregistrements dans les tables
doivent également être exprimées avec la sytaxe d'Hibernate, car l'application durant
son exécution aura souvent besoin de récupérer des données.

Copier le script ci-dessous an de créer la table M_Product_Costing dans le système


de gestion de bases de données relationnelles cible.

Script de création de la table M_Product_Costing :


CREATE TABLE M_Product_Costing(
M_Product_ID INTEGER,
C_AcctSchema_ID INTEGER,
AD_Client_ID INTEGER,
AD_Org_ID INTEGER,
Created DATE DEFAULT SYSDATE NOT NULL,
CreatedBy INTEGER,
Updated DATE DEFAULT SYSDATE NOT NULL,
UpdatedBy INTEGER,
CurrentCostPrice INTEGER,
FutureCostPrice INTEGER,
CostStandard INTEGER,
CostStandardPOQty INTEGER,
CostStandardPOAmt INTEGER,
5.4 Exemple de mapping pour Compiere 40

CostStandardCumQty INTEGER ,
CostStandardCumAmt INTEGER,
CostAverage INTEGER,
CostAverageCumQty INTEGER,
CostAverageCumAmt INTEGER,
PriceLastPO INTEGER,
PriceLastInv INTEGER,
TotalInvQty INTEGER,
TotalInvAmt INTEGER,
CONSTRAINT M_Product_Costing_Key PRIMARY KEY (M_Product_ID, C_AcctSchema_ID)
);

La syntaxe d'Oracle et de Hsqldb étant quelque peu diérente, ce script a été modié
de l'original qui se trouve dans le chier comportant tous les scripts de création des
tables de la base de données (voir section 5.1). Les modications concernent surtout
les déclarations de type, comme par exemple INTEGER.

2. Fichier de conguration
Les chiers de conguration peuvent légèrement varier d'une application à une autre.
Dans mon présent exemple, le chier de conguration sera le même que celui présenté
à la section 5.3.1. Un tel chier peut changer pour plusieurs raisons. L'URL de la
base de données peut par exemple être modiée selon son propre choix. Ce chier
peut également comporter des diérences si le système de gestion de base de données
relationnelles est un autre que Hsqldb. Eectivement chaque système possède son
propre driver ainsi que son propre dialecte qu'il faudra spécier dans la conguration.
Il sut de ne changer que quelques lignes du chier de conguration pour que Hibernate
puisse travailler avec divers SGBDR, ce qui montre une fois encore sa grande exibilité.

3. Création du document de mapping objet / relationnel


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
<class name="com.minosis.hibernate.MProductCosting" table="M_PRODUCT_COSTING">

<composite-id>
<key-property name="M_Product_ID" sql-type="int(4)"
column=M_Product_ID/>
<key-property name=C_AcctSchema_ID sql-type="int(4)"
column=C_AcctSchema_ID/>
</composite-id>

<id name="C_AcctSchema_ID" type="integer">


5.4 Exemple de mapping pour Compiere 41

<column name="C_AcctSchema_ID" sql-type="int(4)"/>


<generator class="increment" />
</id>

<property name="AD_Client_ID" type="integer">


<column name="AD_Client_ID" sql-type="int(4)" not-null="true"/>
</property>

<property name="AD_Org_ID" type="integer">


<column name="AD_Org_ID" sql-type="int(4)" not-null="true"/>
</property>

<property name="IsActive" type="date">


<column name="IsActive" sql-type="date" not-null="true"/>
</property>

<property name="Created" type="date">


<column name="Created" sql-type="date" not-null="true"/>
</property>

<property name="CreatedBy" type="integer">


<column name="CreatedBy" sql-type="int(4)" not-null="true"/>
</property>

<property name="Updated" type="date">


<column name="Updated" sql-type="date" not-null="true"/>
</property>

<property name="UpdatedBy" type="integer">


<column name="UpdatedBy" sql-type="int(4)" not-null="true"/>
</property>

<property name="CurrentCostPrice" type="integer">


<column name="CurrentCostPrice" sql-type="int(4)" not-null="true"/>
</property>

<property name="FutureCostPrice" type="integer">


<column name="FutureCostPrice" sql-type="int(4)" not-null="true"/>
</property>

<property name="CostStandard" type="integer">


<column name="CostStandard" sql-type="int(4)" not-null="true"/>
</property>

<property name="CostStandardPOQty" type="integer">


<column name="CostStandardPOQty" sql-type="int(4)" not-null="true"/>
</property>
5.4 Exemple de mapping pour Compiere 42

<property name="CostStandardPOAmt" type="integer">


<column name="CostStandardPOAmt" sql-type="int(4)" not-null="true"/>
</property>

<property name="CostStandardCumQty" type="integer">


<column name="CostStandardCumQty" sql-type="int(4)" not-null="true"/>
</property>

<property name="CostStandardCumAmt" type="integer">


<column name="CostStandardCumAmt" sql-type="int(4)" not-null="true"/>
</property>

<property name="CostAverage" type="integer">


<column name="CostAverage" sql-type="int(4)" not-null="true"/>
</property>

<property name="CostAverageCumQty" type="integer">


<column name="CostAverageCumQty" sql-type="int(4)" not-null="true"/>
</property>

<property name="CostAverageCumAmt" type="integer">


<column name="CostAverageCumAmt" sql-type="int(4)" not-null="true"/>
</property>

<property name="PriceLastPO" type="integer">


<column name="PriceLastPO" sql-type="int(4)" not-null="true"/>
</property>

<property name="PriceLastInv" type="integer">


<column name="PriceLastInv" sql-type="int(4)" not-null="true"/>
</property>

<property name="TotalInvQty" type="integer">


<column name="TotalInvQty" sql-type="int(4)" not-null="true"/>
</property>

<property name="TotalInvAmt" type="integer">


<column name="TotalInvAmt" sql-type="int(4)" not-null="true"/>
</property>

</class>
</hibernate-mapping>

A noter que les chiers de mapping peuvent être très volumineux dans des applications
importantes. D'une part en raison du nombre important d'attributs dans la table et
également suivant le degré de précision dans les déclarations.
5.4 Exemple de mapping pour Compiere 43

Ce chier dénit 22 attributs, la clé primaire étant une clé composée de M_Product_ID
et C_AcctShema_ID. Cette clé composée est dénie par la balise <composite-id>
qui peut représenter une clé primaire composée d'un nombre indéterminé d'attributs.

4. Fichiers de manipulation

La table M_Product_Costing contient plusieurs informations sur des produits, essen-


tiellement sur leurs coûts actuels, futurs et il est également possible de connaître une
moyenne du prix du produit sur une période déterminée. Le code ci-dessus insère des
éléments dans la base de données, la syntaxe est en SQL classique. Un buer de type
string contenant la requête à eectuer est créé. Toutes ces lignes de code peuvent
paraître complexes après avoir travaillé avec Hibernate.
Eectivement, une fois que le chier de conguration et le chier de maping sont
créés, les manipulations (insertions, traitement de données) sont assez triviales. Pour
pouvoir employer Compiere avec Hsqldb, il faudrait modier le code ci-dessus de la
sorte.

• Initialisation d'Hibernate

SessionFactory sessions = new Conguration().congure().buildSessionFactory();


Session session =sessions.openSession();
Transaction tx = session.beginTransaction();

• Insertion d'un enregistrement dans la base de données Hsqldb

M_Product_Costing product = new M_Product_Costing product();


product.setM_Product_ID( );
5.4 Exemple de mapping pour Compiere 44

product.setC_AcctSchema_ID( );
product.setAD_Client_ID( );
product.setAD_Org_ID( );
product.setIsActive(Y);
product.setCreated(sysDate, p ex :2003-01-20 19:55:24.0);
product.setCreatedBy(0);
product.setUpdated(sysDate);
product.setUpdatedBy(0);
product.setCurrentCostPrice(0);
product.setCostStandard(0);
product.setFutureCostPrice(0);
product.setCostStandardPOQty(0);
product.setCostStandardPOAmt(0);
product.setCostStandardCumQty(0);
product.setCostStandardCumAmt(0);
product.setCostAverage(0);
product.setCostAverageCumQty(0);
product.setCostAverageCumAmt(0);
product.setPriceLastPO(0);
product.setPriceLastInv(0);
product.setTotalInvQty(0);
product.setTotalInvAmt(0);

• Sauvegarde de l'enregistrement et fermeture de la session

session.save(contact);
tx.commit();
session.close();

Ce code peut paraître long pour une simple insertion dans une table, mais l'écrire
de cette façon permet de séparer chaque attributs pour une meilleure compréhension.
Si l'on désire une version plus compacte, ce code peut aussi être écrit de la manière
suivante :

• M_Product_Costing product = new M_Product_Costing product( ,  ,  ,  ,  Y,2003-


01-20 19:55:24.0, 0, 2003-01-20 20:58:31.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );

Le code présenté initialise un enregistrement vide dans la table. Des enregistrements


sont ajoutés par la suite simplement en aectant des valeurs au diérents attributs.
Cet exemple montre les étapes à eectuer pour une seule table de Compiere. De plus,
seule l'insertion dans la base de données à été traitée et non la récupération d'objets
(voir section 5.3.3). Lorsqu'il n'y a pas beaucoup de tables à prendre en considération,
les tâches à eectuer ne sont pas très complexes. Cependant, pour un projet tel que
Compiere, ça demande un travail énorme surtout en raison du très grand nombre de
tables dans la base de données. Eectivement, Hibernate doit avoir connaissance de
chacune d'elles pour pouvoir mapper les objets correctement. Une diculté supplémen-
taire apparaît avec l'emploi des triggers (voir section 4.2.3).
45

6 Conclusion

6.1 Expériences faites durant la réalisation du projet


Ce sont principalement de nouveaux programmes, systèmes et technologies que m'a fait
connaître ce projet.
Tout d'abord, j'ai découvert Hibernate, un framework dont je n'avais jamais entendu
parler. J'ai pu me rendre compte, à travers de tests, de divers articles et extraits de
programmes réalisés à l'aide d'Hibernate, de la puissance de ce Framework. Il peut
paraître assez long de créer des projets avec Hibernate en raison du nombre important de
chiers à générer pour son fonctionnement. Cependant, une fois l'application terminée,
il est possible de l'employer avec de nombreux systèmes de gestion de base de données.
Quelques changements du chier de conguration permettent de réaliser rapidement et
ecacement cette opération. Ceci me paraît être un très grand avantage avec, de nos
jours, l'apparition continue de nouveaux systèmes sur le marché. Bien que dans ce projet
un faible pourcentage des possibilités qu'ore Hibernate a été employé, je pense que
sa philosophie et son but ont été clairement dénis et de nombreux exemples aident à
comprendre comment démarrer pour réaliser une application de grande envergure. Bien
plus que de s'attarder sur tous les petits détails de syntaxe et le long travail répétitif qui
apparaîtraient lors de l'implémentation de Compiere avec Hibernate, il me paraissait
important de donner un exemple de fonctionnement pour une seule table.
Pour ce qui est de la base de données, mon idée était de trouver une base de données
légère pour enregistrer les éléments créer à l'aide d'Hibernate an de pouvoir faire des
tests rapidement, sur n'importe quelle machine. Eectivement, Oracle prend énormé-
ment de ressources, ce qui pénalise tout le système. J'ai donc découvert Hsqldb, que je
trouve très intéressant. Bien sûr ce produit n'est pas comparable du point de vu de ses
fonctionnalités avec un système comme Oracle, mais il est amplement susant pour de
petites applications personnelles.
J'ai également employé Compiere pour réaliser des tests et ce logiciel me paraît très
puissant et complet, son indéniable avantage étant bien sûr qu'il est gratuit et facilement
paramétrable selon les envies de chacun.
Ce qui m'a également impressionné durant la réalisation de ce projet est de voir
la complexité d'un programme tel que Compiere et les problèmes qui peuvent être
engendrés par le changement de quelques petites lignes de code. Cette complexité
provient en grande partie du fait que Compiere est un logiciel déjà très évolué et qu'il
faut comprendre la logique des programmeurs sur la construction et les standards de
programmation de ce logiciel.
Je pense que l'emploi d' Hibernate va se généraliser dans les années à venir, à moins
qu'il y ait une révolution dans le domaine des bases de données, notamment peut-être
avec l'apparition et la standardisation des bases de données objets.
Quoiqu'il en soit, le dé de rendre Compiere indépendant face aux bases de données
en employant Hibernate est la meilleure des manières de progresser dans divers domaines
6.2 Résultats du pro jet 46

comme les bases de données, la programmation orientée objets, le travail avec des
serveurs...

6.2 Résultats du projet


L'idée initiale qui était de rendre Compiere indépendant d'Oracle a été remplacée au
cours du projet par une étude de faisabilité de ce but ainsi que l'enregistrement d'un
objet créé par Compiere dans une base de données d'un autre type qu'Oracle. Ce
changement est apparu pour des raisons de temps et de complexité.
La section 5.4 décrit la marche à suivre pour enregistrer un objet de Compiere dans
une base de données à l'aide d'Hibernate. Il est possible de réaliser cette démarche pour
le logiciel Compiere en entier mais cela équivaut pratiquement à la réécriture complète
d'un logiciel car chaque chier ou presque doit être modié.
Cependant tout n'est pas si facile et des complications apparaissent rapidement pour
adapter complètement Compiere à l'aide d'Hibernate. Eectivement, la base de données
de Compiere est fortement liée aux triggers, ce qui entraîne des complications, comme
expliqué à la Section 4.2.3. Ce problème peut être surmonté en détachant les triggers de
la base de données et en les traitant à un niveau supérieur, c'est à dire au même niveau
qu'Hibernate. Cependant cette manière de procéder entraîne un travail supplémentaire
considérable et peut hypothéquer l'utilisation d'Hibernate pour un projet tel que celui-
ci.
Annexe A 47

Annexe A : Tutorial d'installation

Cette annexe décrit le processus d'installation de Compiere


1.1 Pré-requis
Compiere nécessite de télécharger tout d'abord certains logiciels, lesquels sont mention-
nés dans les 3 points ci-dessous.

1. Télécharger Oracle
11 version 10g

2. Télécharger Java
12

3. Télécharger Compiere
13

1.2 Etapes pour l'installation


Pour le bon fonctionnement de Compiere, il est impératif de réaliser chaque étape dans
l'ordre. Il faut également vérier que le réseau est conguré avec un serveur DNS, ne
pas utiliser les adresses IP mais les noms!

1.3 Installation d'Oracle


Compiere fonctionnant pour l'instant uniquement avec une base de données Oracle, il
est nécessaire d'installer ce système de bases de données sur votre propre machine ou
sur un serveur. Cette étape est facultative dans le cas où Oracle 10g est déjà installé et
proprement conguré sur la machine qui accueillera Compiere ou si vous possédez déjà
un serveur de base de données avec Oracle installé. Dans le cas contraire :

1. Décompresser le chier téléchargé 10g_win32_db sur votre disque dur.

2. Ouvrir le répertoire obtenu et exécuter le chier setup du répertoire install.

3. Indiquer la source et la destination dans les champs respectifs.

4. Installer la version Standard Edition.

5. Type de la base de données à créer : universel (usage général).

6. Choisir un nom pour la base de données (ex : dbcompiere).

7. Suivre les instructions


11 http://www.oracle.com, dernière visitele 05.11.2005
12 http://www.java.sun.com, dernière visitele 05.11.2005
13 http://www.compiere.org, dernière visitele 10.11.2005
Annexe A 48

L'installation nécessite un certain temps et prend environ 6 GB, ces derniers comprenant
l'image et l'installation. Il est vivement conseillé d'avoir 1 GB de mémoire vive installé
pour un fonctionnement optimal.
Remarque : Il est très utile d'avoir un serveur spécialement dédié pour Oracle. Ef-
fectivement, le fait de l'installer sur la même machine que celle employée pour travailler
demande énormément de ressources et se fait ressentir sur les autres applications.
Une fois l'installation eectuée, il faut vérier qu' il n'y a pas eu d'erreurs et si Oracle
est opérationnel.

Test du bon fonctionnement de la base de données :


• Ouvrir une invite de commande sous Windows

• Exécuter tnsping <nom base de données>.

• Un 'Ok' devrait apparaître avec entre parenthèses le temps qu'il a fallu pour tester
la base de données. En cas de problèmes, s'assurer que la machine utilise le DNS
et non le localhost ou l'adresse IP directement. Les sources d'erreurs peuvent être
si nombreuses qu'il n'est pas possible de donner une solution pour chacune. Si le
problème persiste, voir sur le site ociel d'Oracle la documentation complète de
l'installation.

Lorsque la base de données fonctionne, il est possible de l'atteindre en ouvrant une


fenêtre explorer et d'y introduire l'adresse suivante (par défaut) :

• http://Nom_machine:5500/em où Nom_machine est le nom de la machine sur


laquelle Oracle a été installé. Si votre machine s'appelle CACAO, voici l'adresse a
introduire : http://CACAO:5500/em

Il faut à présent les mots de passe nécessaires (dénis lors de l'installation) pour accéder
à l'interface d'administration de la base de données et ainsi pouvoir eectuer toutes les
opérations désirées.

1.4 Installation de Java


Java est indispensable au fonctionnement de Compiere, celui-ci ayant été développé
avec ce langage de programmation. Par défaut, la plupart des machines ont Java
installé et il est donc inutile de répéter cette étape. Si ce n'est pas le cas, simplement
le télécharger à l'adresse indiquée précédemment et exécuter le chier setup tout en
suivant les instructions.

1.5 Installation du Serveur compiere


Le serveur d'application de Compiere est le premier composant à installer. Il con-
stitue l'application elle-même, celle à laquelle vont se connecter les futurs utilisateurs
de Compiere.
1. Conguration nécessaire pour le serveur Compiere :
Annexe A 49

• Oracle 10g et Java installés (eectué au point 2.2.1 et 2.2.2)

• Espace disque libre supérieure à 5 GB(base de données incluse)

• Mémoire : minimum 512 MB, recommandé 1 GB

• Connection TCP/IP pour les clients

2. Installation

• Décompresser le chier Compiere : on suppose que le répertoire d'installation est


C:\Compiere2

• Exécuter RUN_setup du répertoire C:\Compiere2

Figure A.1: Interface de conguration du serveur Compiere

Une fenêtre similaire à la Figure A.1 apparaît et contient la liste de paramètres qu'il
faudra éventuellement modier.
Annexe A 50

Description de tous les paramètres :


• Java Home : indiquer le répertoire de votre disque dur dans lequel est installé Java.

• Compiere Home : indiquer le répertoire de votre disque dur dans lequel Compiere
est installé.

• Apps Server : Serveur où se trouve l'application (Compiere).

• Web Port : port web (http, www) par défaut 80.

• Database Type : Détecte les SGBD disponibles (Oracle, éventuellement Sybase).


Sélectionner celui de votre choix.

• Database Server : Serveur où se trouve la base de données. Dans le cas où la base


de données et le serveur d'application sont installés sur le même serveur, Apps
Server = Database Server.

• Database Name (SID) : Identiant de la base de données, dérivé du nom TNS (=


nom global). Si le TNS s'appelle train.compiere.org, l'identiant (SID) aura la
valeur train.

• Database Port : port de communication avec la base de données. Par défaut:1521.

• Database User : par défaut cette valeur est compiere.

• Mail Server : indiquer votre serveur mail si vous en disposez.

• Mail User : mail utilisateur.

• JNP Port : port RMI/JNP standard (1099).

• SSL : Compiere a besoin d'un certicat SSL (Secure Socket Layer) . Un certicat
est crée automatiquement situé dans : Compiere_Home/Keystore/myKeystore.

• Key Store Password : mot de passe généré automatiquement pour le certicat.

• TNS name : nom global de la base de données.

• System password : mot de passe déni pour l'administrateur système (tous les
privilèges) lors de l'installation d'Oracle.

• Database password : mot de passe de la base de données (par défaut = compiere).

• Admin E-mail : par défaut admin@company.com. Choisir l'adresse désirée. A


noter qu'un serveur IMAP est nécessaire. Si vous ne possédez pas de serveur
SMTP, entrez simplement le nom d'un serveur valide. Ceci est nécessaire pour que
la conguration se termine avec succès. Sans serveur valide, une erreur sera levée.

• Mail Password : mot de passe pour le compte e-mail.


Annexe A 51

Remarque : les numéros de ports peuvent être modiés. Il faut cependant faire
attention à ne pas choisir un port réservé, ce qui entraînerait des conits. Lors de
changement de numéro de port, il faut également en avertir l'application en question
(p ex. Oracle). De plus, l'emploi d'un rewall peut nécessiter la création de nou-
velles exceptions destinées à laisser un programme utilisant un certain port eectuer
ses actions.

Cliquer sur le bouton 'Test' au bas et à gauche de la fenêtre pour vérier que les
paramètres entrés fonctionnent. En cas de problème, le test s'interrompt et le carré à
droite de la case de chaque paramètre devient rouge.
Il est impératif que le test fonctionne pour continuer, changer les paramètres (vérier
bien les mots de passe) et réessayer autant de fois que nécessaire.
Si le test réussit, la case devient verte et comporte un petit vu. Une fois que le test
réussi intégralement, cliquer sur 'save' : ceci aura pour eet de créer le serveur.

1.6 Conguration environnement/Importation base de données


Conguration de l'environnement
Le répertoire C:\COMPIERE_HOME/utils contient des scripts utilisés pour des opéra-
tions sur le serveur

A contrôler : le script myEnvironment :

• Contrôler la conguration pour COMPIERE_HOME et JAVA_HOME

• Contrôler la valeur de COMPIERE_DB_TNS (Global Database Name)

• Contrôler le mot de passe du SYSTEM (COMPIERE_DB_SYSTEM=password)

• Si une entrée est incorrecte, ne pas la changer directement via ce script mais via
le script RUN_setup (voir 2.2.3)

Le nom global de la base de données est équivalent au TNS de la base de données,


ces deux termes variant uniquement de par leur nom. Il est nécessaire de s'assurer
encore une fois que le serveur de la base de données Oracle est bien accessible. Pour
ce faire, eectuer à nouveau la commande tnsping dans une invite ms-dos : tnsping
<tns name>
Importation de la base de données
Exécuter le script RUN_ImportCompiere situé dans le répertoire
C:\COMPIERE_HOME\utils
Annexe A 52

Figure A.2: Résultat du script

La Figure A.2 représente le résultat à obtenir à la n de l'exécution. Durant l'exécution,


des avertissements devraient apparaître, ce qui est normal à ce stade, il sut simplement
de les ignorer.

Remarque :
exécuter à nouveau le script RUN_Env du répertoire C:\COMPIERE_HOME/utils.
Cette fois, il ne devrait y avoir aucune erreur.

1.7 Fin de l'installation


Exécuter RUN_Server2 du répertoire C:\COMPIERE_HOME/utils.

Le script prend quelques minutes pour s'exécuter et vous ne devriez pas obtenir d'erreurs.
Problème fréquent à ce stade: un port est déjà employé. Dans ce cas, relancer la com-
mande RUN_setup (voir 2.2.3) et modier le port14 en question. Pour tout changement
que vous voudriez eectuer, il est impératif de passer par RUN_setup.

1.8 Démarrage d'une interface client Compiere


Conguration requise :

• Plateforme Java

• Mémoire sur disque : 3 MB

• Mémoire : min 128 MB, 256 MB recommandés


14 Liste des ports : http://www.iana.org/assignments/port-INTEGERs
Annexe A 53

• Achage : 1024*768 ou mieux

• Connexion TCP/IP au serveur

L'installation du serveur Compiere étant terminée, des clients peuvent à présent s'y
connecter et enn débuter dans leur apprentissage de ce logiciel.
Remarque : une interface client est automatiquement installée sur la même machine
que le serveur. Il n'y donc pas besoin d'installer une nouvelle fois cette interface si le
client est démarré depuis le serveur où est installé le serveur Compiere.
Dans le cas où vous voulez installer une interface client depuis une machine diérente
de celle sur laquelle est installé le serveur :

• Ouvrir un browser internet et y introduire l'adresse du serveur d'application.

• Cliquer sur le lien en format zip de la ligne Local Install.


Démarrer le client :
Cliquer sur le raccourci du bureau (ou depuis le menu démarrer) sur Compiere2. A
l'écran apparaît une fenêtre similaire à la Figure A.3, la fenêtre de login pour Compiere.

Figure A.3: Identication

Cliquer sur le champ Host (probablement rouge pour l'instant). Apparaît alors une
boîte de dialogue semblable à la Figure A.4. Entrez toutes les informations demandées
par chacun des champs. L'application trouve normalement la plupart des champs de
façon automatique. Il est nécessaire de tous les vérier et de compléter/corriger les
informations manquantes ou incorrectes.
Annexe A 54

Figure A.4: Paramètres de connexion à la base de données

Cliquer sur 'Test Database' pour vérier que le serveur de bases de données soit
accessible. Cliquer enn sur le vu vert pour vous ramener à l'écran de login (Figure
A.3).
Champ Host : si le champ est tout blanc, une connexion a été faite (durant le test)
au serveur d'application.
Un champ important et souvent créateur de problèmes est le champ 'Firewall Port'.
Eectivement, un pare-feu peut bloquer des requêtes vers le serveur, il s'agit de con-
naître parfaitement la conguration de son pare-feu pour y remédier car c'est une erreur
fréquente et parfois compliquée à détecter.
Si seulement le début du champ est rouge, une connexion a été établie à la base de
données mais pas au serveur d'application.
Cliquer sur 'Enter', une fenêtre similaire à la Figure A.5 apparaît.
Annexe A 55

Figure A.5: Paramètres de connexion à l'application

La connexion est maintenant établie et un rôle doit être choisi pour l'utilisateur en
question. Compiere fournit les possibilités de login suivantes :

Nom d'utilisateur Mot de passe Role Description


System System System Administrator l'administrateur système
SuperUser System tous tous les accès aux données de l'application
GardenAdmin GardenAdmin GardenWorld Admin Ex: Administrateur Client
GardenUser GardenUser GardenWorld User Ex : Client

1.9 Mises à jour


Depuis la version 2.4.4, plus besoin de désinstaller l'ancienne version pour mettre la
nouvelle.
Etapes :
• Eacer le sous-répertoire jboss

• Décompresser le chier de la nouvelle version

• Exécuter RUN_setup

• Migrer la base de données existante ou importer la nouvelle base de données

1.10 Désinstallation de Compiere


Compiere ne dispose pas d'une procédure de désinstallation très propre. Après avoir
eacé le répertoire principale, il faudra eacer manuellement les chiers restant.
Etapes :
Annexe A 56

• Eacer la base de données Compiere

• Eacer le répertoire COMPIERE_HOME

• Eacer toutes les variables d'environnement Compiere ainsi que la variable d'envi-
ronnement du PATH
Annexe B 57

Annexe B : Package org.compiere.db


Ce package contient un grand nombre de classes qui permette de créer, modier ou
eacer la base de données. Il contient 36 classes et une interface. Le chemin complet
de ce package est : $\compiere-all\dbPort\src\org\compiere\db .
Ci-après seront expliqués quatre classes et l'interface. Ce choix me paraissait judi-
cieux car ces quatre classes représentent la partie la plus importante du package et la
plus intéressante. Un grand nombre des autres classes présentes ne comportent que
des traductions de termes employés (port rewall, connexion dédiée..) à travers la
construction d'un objet de type String.

Figure B.1: Package org.compiere.db

Org est le package principal, compiere étant vu comme un sous package (com-
piere.org.db). A noter encore une fois que les classes mentionnées du package com-
piere.org.db ne sont pas exhaustives mais représentent un échantillon. Compiere-
Database est une interface. Pour chaque classe présente sur le graphique du package
de la Figure B.1, quelques méthodes seront décrites.
Pour ces classes, sont présentés dans l'ordre :

• Le constructeur de la classe

• Les attributs de la classe

• Les méthodes de la classe.

Cette structure permet par la suite une meilleure vue des relations entre les classes ainsi
qu'une comparaison entre les diérentes classes.
Annexe B 58

1.1 Classe CConnection

Figure B.2: Classe CConnection

CConnection est pour Compiere Connection, c'est donc une classe qui gère les con-
nexions vers le serveur Compiere. Elle ore beaucoup de fonctionnalités comme par
exemple des méthodes de recherche de serveur ou alors de tests d'applications et de
serveurs. Elle contient également des fonctions de tests de la base de données et de
recherche d'informations (versions, drivers...) sur les composants utilisés.

Constructeur : CConnection

le constructeur n'a pas été redéni, c'est donc celui par défaut (sans arguments) qui est
employé.

Création d'un nouvel objet de type CConnection : s_cc = new CConnection () . s_cc
est alors un objet de type CConnection et peut invoquer toutes les méthodes dénies
dans cette classe.

Attributs
Deux attributs principaux interviennent dans les méthodes décrites ci-après : s_cc et
log.
Initialisation de ces deux attributs :

private static CConnection s_cc = null;


private static CLogger log = CLogger.getCLogger (CConnection.class);

s_cc est initialiséà null et représente un objet de type CConnection. Une fois initialisé
il possède donc les caractéristiques (attributs + méthodes) d'un objet CConnection.
s_cc sera employé pour vérier si une connexion est déjà présente ou alors lors d'une
nouvelle connexion.
Annexe B 59

log est initialisé avec les paramètres de login d'un objet de type CConnection. Il
contiendra des paramètres de logging pour démarre Compiere, comme par exemple un
nom d'utilisateur associé à un mot de passe.

Méthodes
1. méthode testDatabase
public Exception testDatabase () {
...
}

Fonction servant à tester la base de données. Une connexion est recherchée à l'aide de la
fonction getConnection(). Si une erreur quelconque se produit, une exception est levée.
Si la fonction testDatabase réussit, des informations spéciques à la base de données
sont enregistrées dans un tableau nommé m_info[] suivant le pseudo-code ci-dessous :

m_info[0] = DatabaseName + version


m_info[1] = DriverName + version

Les informations sauvegardées dans ce tableau à deux entrées peuvent par la suite
être utilisées de diverses façons, par exemple pour simplement acher à l'écran ces
informations qui auraient été demandées par un utilisateur.

2. méthode testAppsServer
public Exception testAppsServer () {
if (setAppsServerInfo ())
testDatabase ();
return getAppsServerException ();
}
Cette fonction sert à tester le bon fonctionnement du serveur d'application, dans notre
cas ce serait le serveur sur lequel Compiere est installé.

La fonction setAppsServerInfo () sert à modier / mettre à jour le serveur d'application.


La fonction testAppsServer () vérie en premier lieu que le serveur peut être accédé et
donc également mis à jour.

Si tel est le cas, la fonction testDatabase() est exécutée. Cette fonction est exécutée car
le serveur d'application a besoin de la base de données pour fonctionner. Si le serveur
d'applications fonctionne et que la base de données ne fonctionne pas, aucun travail
ne peut être entrepris et c'est donc le test de la base de données qui renverra l'erreur.
De cette façon, il y a une nette séparation entre les erreurs provenant de la base de
données de celles provenant du serveur d'applications et ainsi les erreurs peuvent être
facilement localisées puis corrigées.
Annexe B 60

3. méthode setDbName
public void setDbName (String db_name) {
m_db_name = db_name;
m_name = toString ();
m_okDB = false;
}
Fonction utilisée pour assigner un nom à la base de données. Les champs m_db_name
et m_name sont de type String tandis que m_okDB est de type boolean (true /
false). L'argument de la fonction est le nom donné à la base de données, il est aecté
au champ m_db_name.
m_name est le nom de la connexion, il est déni par défaut avec la valeur Standard.
Il est possible également de créer des connexions avec un nom personnalisé. m_okDB,
qui correspond à la connexion avec la base de données et qui a la valeur true dans le
cas où une connexion est établie, est mis à 'false'. La raison en est qu'on ne peut pas
savoir si après l'exécution de cette fonction, il y a ou non une connexion établie. Cette
valeur sera mise à true par exemple lorsque la fonction getConnection sera eectuée et
qu'elle n'aura renvoyé aucune exception.

1.2 Classe Database


La classe Database comprend des informations générales ainsi que des constantes con-
cernant diérentes bases de données.

Figure B.3: Classe Database


Annexe B 61

Constructeur : Database

le constructeur n'a pas été redéni, c'est donc celui par défaut (sans arguments) qui
est employé. Création d'un nouvel objet de type Database : Database essai = new
Database () .

Attributs
public static String DB_ORACLE = "Oracle";
public static String DB_POSTGRESQL = "PostgreSQL";
public static String DB_SYBASE = "Sybase";
public static String DB_MSSQLServer = "SQLServer";
public static String DB_DB2 = "DB2";
public static String DB_MYSQL = "MySQL";

Les attributs sont déclarés static et sont donc des champs de classe, c'est à dire des
propriétés propres à la classe et pas spéciques aux objets créés. Ces constantes con-
tiennent le nom des principaux systèmes de bases de données. Elles sont employées
également dans d'autres classes, par exemple pour vérier la base de données présente
sur le serveur et émettre un avertissement si cette dernière n'est pas compatible avec
Compiere. Rappelons que pour le moment, seuls deux systèmes de bases de données
fonctionnent avec Compiere : Oracle et Sybase.

public static String[] DB_NAMES = new String[] {


DB_ORACLE, DB_SYBASE
};

DB_NAMES est un tableau de string comportant les deux bases de données valides.
Dans la classe CreateCompiere on verra comment est employée cette information.

protected static Class[] DB_CLASSES = new Class[] {


DB_Oracle.class, DB_Sybase.class
};

DB_CLASSES est un tableau d'objets Class et comporte des instances de type Oracle
et Sybase.

public static int CONNECTION_TIMEOUT = 10;

CONNECTION_TIMEOUT indique le temps à attendre avant de pouvoir armer que


la connection n'arrive pas être établie. Dans ce cas, ce temps est de 10 secondes.

Méthodes La classe Database ne dénit pas de méthodes. Comme cité plus haut,
c'est une classe regroupant des constantes importantes pour le traitement des bases de
données.
Annexe B 62

1.3 Classe CreateCompiere


La classe CreateCompiere permet de créer une nouvelle base de données Compiere. Ses
deux fonctions principales sont donc :

1. Créer un utilisateur

2. Créer la structure de la base de données (tables, fonctions, procédures...)

Figure B.4: Classe CreateCompiere

Constructeur : CreateCompiere
Le constructeur a été redéni an de pouvoir accepter quatre arguments.

public CreateCompiere (String databaseType, String databaseHost, int databasePort, String system-
Password) {
initDatabase(databaseType);
m_databaseHost = databaseHost;
if
(databasePort == 0)
m_databasePort = m_dbTarget.getStandardPort();
else
m_databasePort = databasePort;
m_systemPassword = systemPassword;
Annexe B 63

log.info(m_dbTarget.getName() + " on " + databaseHost);


}
1. String databaseType : représente le type de la base de données. Cinq types de bases de données sont
dénis (dans la classe Database, voir ci-dessus)
2. String databaseHost : serveur accueillant la base de données
3. int databasePort : port utilisé par la base de données
4. String systemPassword : mot de passe système de la base de données

Une fois les quatre arguments fournis, la fonction initDatabase est eectuée. Cette
dernière prend en argument un type de base de données. Elle parcourt le tableau de
String DB_NAMES crée dans la classe Database pour vérier que le type de la base de
données donné en argument de initDatabase se trouve eectivement dans ce tableau.
Comme dans ce tableau de String on ne retrouve que Oracle et Sybase, la fonction
initDatabase renverra une erreur si le type de la base de données est diérent de ces
deux valeurs. Cette fonction sert donc à s'assurer qu'un système de base de données
compatible avec Compiere est présent.
Une fois la fonction initDatabase eectuée, le nom de l'Host de la base de données
est aecté à m_databaseHost. Après cette étape, c'est le port de la base de données
qui est analysé. Si le port donné en argument de la fonction vaut 0, cela signie que
le port standard est employé (1521 par défaut pour Oracle). Si le numéro de port
donné en argument est diérent de 0, le port désiré et donné en argument est employé.
En dernière étape, c'est la dénition du mot de passe système. La dernière ligne du
constructeur a pour eet d'acher le nom de la base de données ainsi que le nom du
serveur/ordinateur sur lequel est installé le système de base de données.
Création d'un nouvel objet de type CreateCompiere :
CreateCompiere cc = new CreateCompiere (Database.DB_SYBASE, "dev2", 0, "");
La ligne ci-dessus a pour eet de créer une nouvelle base de données de type Sybase
située sur le serveur dev2 avec 0 comme port de communication. Le dernier argument
représenté par des guillemets signie qu'aucun mot de passe n'est déni.

Attributs :
(1) private String m_compiereUser = null;
(2) private String m_compierePassword = null;
(3) private String m_databaseName = null;
(4) private String m_databaseHost = null;
(5) private int m_databasePort = 0;
(6) private String m_systemPassword = null;
(7) private String m_databaseDevice = null;
(8) private CompiereDatabase m_dbTarget = null;

Tous les attributs sont initialisés à null car leurs valeurs doivent être fournies lors de
l'installation et par l'utilisateur lors des premières connexions.
Annexe B 64

1. Inititalisé à null et la valeur de l'utilisateur qu'on désire créer lui est aecté. Voir

la fonction setCompiereUser ci-dessous.

2. Contient le mot de passe associé au nouvel utilisateur crée.

3. Nom de la base de données. Utilisé par exemple dans la fonction testConnection()

et createDatabase ci-dessous.

4. Adresse du serveur accueillant la base de données : à spécier durant l'installation.

5. Port de la base de données: à spécier durant l'installation. Si non spécié, aec-

tation du numéro de port standard.

6. Mot de passe système : utile pour se connecter sans devoir obligatoirement créer

un nouvel utilisateur.

7. Informations supplémentaire sur la base de données.

8. Peut contenir deux valeurs : Oracle ou Sysbase. m_dbTarget = (Compiere-


Database)Database.DB_CLASSES[i]. newInstance (); Comme on l'a noté avant,
DB_CLASSES a été initialisé dans la classe Database. Ce champ contient donc le

nom du système de base de données avec lequel Compiere travaille.

Méthodes
MéthodeCreateDatabase
public boolean createDatabase (Connection sysConn)
{
log.info(m_databaseName+"("+m_databaseDevice+")");
return
executeCommands(m_dbTarget.getCommands(CompiereDatabase.CMD_CREATE_DATABASE),
sysConn, true, false);
}
Fonction pour la création de la base de données, renvoie true si tout a fonctionné.

Méthode setCompiereUser
public void setCompiereUser (String compiereUser, String compierePassword)
{
m_compiereUser = compiereUser;
m_compierePassword = compierePassword;
}
Fonction utilisée pour créer un nouvel utilisateur avec son mot de passe associé.
Annexe B 65

Méthode setDatabaseName
public void setDatabaseName (String databaseName, String databaseDevice)
{
m_databaseName = databaseName;
m_databaseDevice = databaseDevice;
}
Fonction utilisée pour congurer le nom et les devices de la base de données.

1.4 Classe TestConnection

Figure B.5: Classe TestConnection

Comme son nom l'indique, cette classe contient des méthodes pour tester la connexion
vers la base de données. Les temps de connexions sont analysés en millisecondes. Des
temps trop longs peuvent entraîner des erreurs.

Constructeur : TestConnection
Le constructeur déni prend trois arguments en paramètre : public TestConnection
(String jdbcURL, String uid, String pwd)
• jdbcURL : Url de la base de données

• uid : utilisateur

• pwd : mot de passe


Annexe B 66

Exemple de test :

String url = "jdbc:oracle:thin:@//24.151.26.64:1521/lap11";


String uid = "compiere";
String pwd = "compiere";
TestConnection test = new TestConnection(url, uid, pwd);

Ce test a pour eet de vérier la connexion de la base de données à l'adresse spéciée


dans l'attribut url.

Attributs
(1) private String m_jdbcURL;
(2) private String m_uid = "compiere";
(3) private String m_pwd = "compiere";
(4) private String m_sql = "SELECT * FROM AD_Element";
(5) private Connection m_conn;

1. Contient l'adresse de la base de données. Exemple d'utilisation : driver = Driver-


Manager.getDriver(m_jdbcURL); Cette ligne récupère le driver de la base de données
dont l'adresse est spéciée en argument (m_jdbcURL).

2. Attribut dénissant un utilisateur, initialisé à compiere


3. Attribut dénissant un mot de passe, initialisé à compiere
4. Requête SQL sélectionnant tous les attributs de la table AD_Element

5. Attribut dénissant une instance de connexion

Exemple utilisant ces attributs: m_conn = DriverManager.getConnection(m_jdbcURL, m_uid,


m_pwd);
Une connexion est établie en donnant en argument un Url, un utilisateur et un mot
de passe.

Méthodes
Méthode init
private void init () {
...
}

En premier lieu, cette fonction essaie de trouver le driver correspondant à la base


de données. Si aucun driver n'est renvoyé, une exception est levée. Si un driver est
trouvé mais que sa valeur est dénie à null, une fonction est eectuée pour en créer et
enregistrer un nouveau. Lorsque cette étape est réalisée, un driver a donc été trouvé
ou créé, le temps qu'il a fallu pour trouver / créer le driver est aché en millisecondes.
Annexe B 67

Ensuite, la fonction init essaie de se connecter à la base de données. A nouveau le


temps nécessaire à la connexion est aché et une exception est levée si la connexion ne
peut pas être établie.

Méthode test
private long test () {
...
}
Cette fonction eectue plusieurs tests de connexion. Tout d'abord elle essaie d'ouvrir
une connexion (try {...}), une erreur étant renvoyée dans le cas où un problème surviendrait
(catch{...}). Voici le code correspondant :

try {
m_conn = DriverManager.getConnection(m_jdbcURL, m_uid, m_pwd);
}
catch (SQLException ex)
{
System.err.println("Test get Connection: " + ex);
return -1;
}
Si une connexion a pu être eectuée, le temps nécessaire à son établissement est
aché en millisecondes. Code correspondant :

long totalStart = System.currentTimeMillis();


long start = System.currentTimeMillis();
//.... Tente de créer une connexion .....//
long end = System.currentTimeMillis();
System.out.println("(A) Get Connection = " + (end - start) + "ms");

Par la suite la fonction test() lit des enregistrements dans une base de données et
ache en millisecondes le temps nécessaire pour réaliser cette opération. Tout à la n, la
connexion est fermée et le temps nécessaire total (ouverture de la connexion /fermeture
de la connexion) utilisé pour eectuer l'entier de la fonction est aché. Cette fonction
est utile d'une part pour vérier qu'uine connexion peut être établie sans erreurs et
d'autres parts pour contrôler que les temps d'accès et de tratiements de la base de
données sont dans les normes.

Méthode main
public static void main (String[] args) {
...
}
La méthode main initie quelques arguments (url, uid, pwd) puis crée un nouvel objet
de type Testconnection an de pouvoir tester la connexion.
Annexe B 68

1.5 Interface CompiereDatabase


CompiereDatabase est l'interface employée par les classes qui traite les bases de données
de Compiere. Elle contient plusieurs méthodes à implémenter, utilisées pour manipuler
la base de données. Les classes DB Oracle et DB PostgreSQL implémentent cette
interface. Cette interface fournissant toutes les méthodes nécessaires à la manipulation
de la base de données Compiere et donc qui est très importante, une description de
chacune de ces méthodes est brièvement faite ci-dessous.

Méthodes de l'interface CompiereDatabase :


• void close() : fermeture de la session.

• String convertStatement(String oraStatement) : convertit la syntaxe d'une requête Oracle


en une syntaxe d'un autre système, donné en argument.

• Connection getCachedConnection(CConnection connection, boolean autoCommit,


int transactionIsolation) : pour obtenir le cache d'une connexion. C'est-à-dire que si la
connexion a déjà été eectuée une fois auparavant, on peut mainenant optimiser son démarrage
en reprenant les informations de cette connexion qui se trouve en cache.

• String getConnectionURL(CConnection connection) : pour obtenir l'adresse URL du


serveur an d'eectuer une connexion.

• String getDescription() : renvoie le nom de la base de données et la version.

• Driver getDriver() : renvoie le driver utilisé pour la base de données.

• Connection getDriverConnection(CConnection connection) : renvoie le driver utilisé..

• String getName() : renvoie le nom court (identiant) de la base de données.

• Object getRowID(ResultSet rs, int pos) : retourne l'identiant d'une ligne de résultat.

• RowSet getRowSet(ResultSet rs) : retourne un groupe de résultats (ensemble de ligne).

• int getStandardPort() : renvoie le port standard JDBC.

• String getStatus() : retourne un état, que ça soit l'état d'une connexion, d'un système etc..
la fonction sera implémentée diéremment selon son emploi.

• void setRowID(PreparedStatement pstmt, int pos, Object rowID) : modier une ligne
en connaissant l'Id d'un objet.

• boolean supportsBLOB() : prend la valeur true ou false selon que les Blob sont supportés
ou non. Un Blob est un type de champ chaîne dans une base SQL.

• String toString() : transformation d'un élément en un string.

La description des principales classes et interfaces du package org.compiere.db donne


un aperçu de la création et du fonctionnement de la base de données. Cette dernière
étant l'élément principal dans l'optique du projet, comme le but de ce dernier est de
montrer qu'il est possible de rendre Compiere indépendant envers les bases de données
Annexe B 69

avec lesquelles il travaille. Il est temps à présent de s'intéresser plus en détail à la base
de données, notamment à son architecture, c'est-à-dire ses tables et relations entre elles
ainsi que leur création.
Annexe C 70

Annexe C : Exemple de schéma ER : module Country


Ce schéma représente une petite partie de la base de données de Compiere. Comme
expliqué ci-dessus, les schémas ont été organisés en représentation logiques. Il existe
beaucoup d'autres schémas semblables à celui-ci qui peuvent être trouvés dans le réper-
toire ERModel. Les éléments principaux de ce schéma. sont à présent décrits.

Cette vue mettant en relation les tables ayant un rapport avec Country comprend 8
tables, comme montré à la Figure C.1. Une seule table C_Country est entièrement
déroulée, les autres ayant été rétrécies par souci de place.
Annexe C 71

Description des tables et relations

Figure C.1: Modèle logique

Les clés numériques des tables (clés primaires ou clés étrangères) sont de type Com-
piereKey. Ci-dessous sont décrites seulement trois tables, les cinq tables restantes étant
construites et fonctionnent de manière analogue.
Toutes les tables de Compiere sont crées lors de l'installation et les scripts de créa-
tions sont sous formes SQL. Ci-dessous sont décrits trois scripts.

Table C_Country
Annexe C 72

Script de création :
CREATE TABLE C_Country (
C_Country_ID INTEGER(10, 0) NOT NULL,
AD_Client_ID INTEGER(10, 0) NOT NULL,
AD_Org_ID INTEGER(10, 0) NOT NULL,
Created DATE DEFAULT SYSDATE NOT NULL,
CreatedBy INTEGER(10, 0) NOT NULL,
Updated DATE DEFAULT SYSDATE NOT NULL,
UpdatedBy INTEGER(10, 0) NOT NULL,
Name NVARCHAR2(60) NOT NULL,
Description NVARCHAR2(255),
CountryCode CHAR(2) NOT NULL,
RegionName NVARCHAR2(60) NOT NULL,
ExpressionPhone NVARCHAR2(20) NOT NULL,
DisplaySequence NVARCHAR2(20) NOT NULL,
DisplaySequenceLocal NVARCHAR2(20) NOT NULL,
ExpressionPostal NVARCHAR2(20) NOT NULL,
ExpressionPostal_Add NVARCHAR2(20) NOT NULL,
C_Currency_ID INTEGER(10, 0),
AD_Language VARCHAR2(6),
ExpressionBankRoutingNo NVARCHAR2(20) NOT NULL,
ExpressionBankAccountNo NVARCHAR2(20) NOT NULL,
MediaSize NVARCHAR2(40),
CONSTRAINT C_Country_Key PRIMARY KEY (C_Country_ID) )

Ce script crée la table C_Country. Une fois qu'elle est crée, une modication de la table
est eectuée grâce à la commande ALTER an de dénir les clés étrangères. Les clés
étrangères pourraient également être dénies lors de la création de la table. Cependant,
l'option choisie de modier la table par après est probablement due au fait de l'envie
d'une séparation nette entre la table proprement dite et les relations (clés étrangères)
qu'elle contient. Ceci permet de modier facilement les clés étrangères d'une table sans
avoir à modier la structure physique de la table.

Script de modication :
ALTER TABLE C_Country ADD CONSTRAINT ADLanguage_CCountry
FOREIGN KEY (AD_Language) REFERENCES AD_Language(AD_Language) ;
ALTER TABLE C_Country ADD CONSTRAINT C_CountryClient FOREIGN KEY
(AD_Client_ID)
REFERENCES AD_Client(AD_Client_ID) ;
ALTER TABLE C_Country ADD CONSTRAINT C_CountryOrg FOREIGN KEY
(AD_Org_ID)
REFERENCES AD_Org(AD_Org_ID) ;
ALTER TABLE C_Country ADD CONSTRAINT CCurrency_CCountry FOREIGN KEY
(C_Currency_ID)
REFERENCES C_Currency(C_Currency_ID)
Ce script dénit les quatre clés étrangères de la table C_Country
Annexe C 73

Clé primaire :
• C_Country_ID de type CompiereKey (valeur obligatoire →NOT NULL)

Clés étrangères :
• AD_Client_ID (valeur obligatoire) : fait référence à la table AD_Client située
dans le module Client & Organization. La table AD_Client contient à son tour
beaucoup d'informations sur le client comme par exemple le nom.

• AD_Org_ID : fait référence à la table AD_Org située dans le module Client &
Organization.

• C_Currency_ID : fait référence à la table C_Currency du même module (Country


etc)

• AD_Language : fait référence à la table AD_Language du même module (Country


etc)

Résumé : cette table est la principale de ce module et contient quatre clés étrangères,
deux faisant référence à des tables du même schéma et deux référençant des tables du
module client et organization. Ces deux dernières relations démontrent que ce schéma
n'est pas isolé mais en interaction avec un certains nombres d'autres modules, le tout
formant la base de données intégrale.

Table AD_Language
Script de création :
CREATE TABLE AD_Language (
AD_Language VARCHAR2(6) NOT NULL,
AD_Client_ID INTEGER(10, 0) NOT NULL,
AD_Org_ID INTEGER(10, 0) NOT NULL,
AD_Language_ID INTEGER(10, 0) NOT NULL,
Created DATE DEFAULT SYSDATE NOT NULL,
CreatedBy INTEGER(10, 0) NOT NULL,
Updated DATE DEFAULT SYSDATE NOT NULL,
UpdatedBy INTEGER(10, 0) NOT NULL,
Name NVARCHAR2(60) NOT NULL,
LanguageISO CHAR(2) NOT NULL,
CountryCode CHAR(2) NOT NULL,
IsDecimalPoint CHAR(1) DEFAULT 'Y' NOT NULL CHECK (IsDecimalPoint in ('Y','N')),
DatePattern NVARCHAR2(20),
TimePattern NVARCHAR2(20),
Processing CHAR(1),
CONSTRAINT AD_Language_Key PRIMARY KEY (AD_Language) )
Annexe C 74

Script de modication :
ALTER TABLE AD_Language ADD CONSTRAINT LanguageClient
FOREIGN KEY (AD_Client_ID)
REFERENCES AD_Client(AD_Client_ID) ;
ALTER TABLE AD_Language ADD CONSTRAINT LanguageOrg
FOREIGN KEY (AD_Org_ID)
REFERENCES AD_Org(AD_Org_ID) ;
Ce script dénit les deux clés étrangères de la table AD_Language

Clé primaire :
• AD_Language de type VARCHAR (valeur obligatoire)

Clés étrangères :
• AD_Client_ID: fait référence à la table AD_Client située dans le module Client
& Organization.

• AD_Org_ID: fait référence à la table AD_Org située dans le module Client &
Organization.

Résumé : table uniquement formée d'une clé primaire et de deux clés étrangères. La
seule table de ce module ayant une référence vers la table AdD_language est la table
C_Country.

Table C_Region
Script de création :
CREATE TABLE C_Region (
C_Region_ID INTEGER(10, 0) NOT NULL,
AD_Client_ID INTEGER(10, 0) NOT NULL,
AD_Org_ID INTEGER(10, 0) NOT NULL,
Created DATE DEFAULT SYSDATE NOT NULL,
CreatedBy INTEGER(10, 0) NOT NULL,
Updated DATE DEFAULT SYSDATE NOT NULL,
UpdatedBy INTEGER(10, 0) NOT NULL,
Name NVARCHAR2(60) NOT NULL,
Description NVARCHAR2(255),
C_Country_ID INTEGER(10, 0) NOT NULL,
CONSTRAINT C_Region_Key PRIMARY KEY (C_Region_ID) )
Annexe C 75

Script de modication :
ALTER TABLE C_Region ADD CONSTRAINT C_RegionClient
FOREIGN KEY (AD_Client_ID)
REFERENCES AD_Client(AD_Client_ID) ;
ALTER TABLE C_Region ADD CONSTRAINT C_RegionOrg
FOREIGN KEY (AD_Org_ID)
REFERENCES AD_Org(AD_Org_ID) ;
ALTER TABLE C_Region ADD CONSTRAINT CCountry_CRegion
FOREIGN KEY (C_Country_ID)
REFERENCES C_Country(C_Country_ID) ;
Ce script dénit les trois clés étrangères de la table C_Region

Clé primaire :
• C_Region_ID de type CompiereKey (valeur obligatoire)

Clés étrangères :
• AD_Client_ID : fait référence à la table AD_Client située dans le module Client
& Organization.

• AD_Org_ID : fait référence à la table AD_Org située dans le module Client &
Organization.

• C_Country_ID : fait référence à la table C_Country située dans le même module

Résumé :La table C_Region détient des informations sur une région, chacune étant
identiée par un numéro unique. Chaque région est aectée à un pays, une clé étrangère
faisant ce lien entre C_Region et C_Country. De plus, chaque région contient égale-
ment une référence à un client et une organisation.

Ce petit aperçu rapide de la base de données montre à quel point elle est compexe et
comme il est dangereux de modier des éléments de sa structure en raison du grand
nombre de relations entre tous les composants. Eectivement, ne changer rien qu'un
seul attribut dans une table peut entraîner de nombreuses erreurs si le problème n'a pas
été préalablement profondément étudié. Les développeurs de Compiere sont en train
de réaliser une version de Compiere indépendante de la base de données sous-jacente.
Malgré qu'ils soient professionnels et nombreux dans le développement, ce projet est
en cours depuis déjà quelques mois, ce qui prouvent encore une fois la complexité et
l'immense travail à eectuer pour y parvenir.
Annexe D 76

Annexe D : Logiciels utilisés

Description Version Système d'exploitation Utilisation

Embarcadero ERStudio Viewer 6.6.1 Win XP Visualisation des schémas ER


Hsqldb 1.8.0 Win XP Base de données
Oracle 10g Win XP Tests, obligatoire pour Compiere
Compiere 2.5.1g Win XP Logiciel central, tests
Hibernate 2.1.8 Win XP Persistance d'objets
Eclipse SDK 3.1.0 Win XP Programmation des exemples
Références 77

References
[1] Christian Bauer and Gavin King, Hibernate in Action, Manning Publications, 2005
[2] David Flanagan, Java in a Nutshell, O'Reilly, 4ème édition en français, 2002
[3] Andreas Meier, Introduction pratique aux bases de données relationnelles, Springer, 2002
[4] Magazine, Login, mai 2005
[5] Internet, http://hibernate.org, dernière visite le 05.11.2005
[6] Internet, http://compiere.org, dernière visite le 10.11.2005
[7] Internet, http://oracle.com, dernière visite le 15.09.2005
[8] Internet, http://java.sun.com, dernière visite le 05.11.2005
[9] Internet, http://www.developpez.com, dernière visite le 20.11.2005