Mise en oeuvre de mappings Objet/Relationnels

Mises à jour

  • 2011-10-02: Mise à jour du projet sur le dépôt: passage à JPA 2 pour éviter un conflit avec Hibernate + bugfix sur le fichier persistence.xml: faire un pull, puis un merge, une vérification des éventuels changements et enfin un commit.
  • 2011-09-27: Changement du nom de la relation UE en ue, changement du type xml en character varying1).
  • Si vous avez utilisé le .zip et non le clone du dépôt sur la forge, corriger <type>pom</type> en <type>jar</type> dans le fichier pom.xml

Remarques préalables

  • Ce TP sera à rendre pour le mardi 11/10 par mail sauf contre-ordre. Avant de faire le zip des sources, effectuer mvn clean ou supprimer le répertoire target. Le zip ne doit pas faire plus de quelques dizaines, au maximum centaines de Ko. Spécifier obligatoirement [MIF18 TPORM] dans le sujet du mail de rendu. Un rendu par binôme, trinômes interdits.
    • Le rendu pourra évoluer vers un rendu via la forge si le temps le permet. Cette page sera alors mise à jour et un mail sera envoyé sur la boite des étudiants concernés.
  • Il est prévu pour pouvoir être réalisé sous les salles TP en démarrant sous Linux. Ces salles possèdent en particulier une installation d'Eclipse pré-configurée, ainsi qu'une base PostgreSQL accessible avec le login etudiant et le mot de passe etudiant.
  • Pour le réaliser sur votre propre machine, il faut:
    • Un environnement de développement Java: JDK 1.5+ et l'un des IDE suivants
      • Eclipse avec le plugin maven (disponible via les JBoss tools)
      • Netbeans
      • Un bon éditeur de code et l'outil maven installé en ligne de commande
    • Une base PostgreSQL, l'outil pgAdmin3, avec un compte (login: etudiant / mot de passe: etudiant) pouvant accéder au schéma public de la base postgres2)
  • :!: Configuration maven: attention à la configuration en salle TP, sous peine de remplir votre compte utilisateur très rapidement.

Introduction

L'objectif de ce TP est de mettre en place un mapping Objet/Relationnel via l'API JPA.

Quelques liens:

Schema relationnel

On considère le schéma relationnel suivant (syntaxe PostgreSQL):

-- Table: departement
 
-- DROP TABLE departement;
 
CREATE TABLE departement
(
  nom CHARACTER VARYING(100) NOT NULL,
  CONSTRAINT pk_departement PRIMARY KEY (nom)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE departement OWNER TO etudiant;
 
-- Table: ue
 
-- DROP TABLE ue;
 
CREATE TABLE ue
(
  code CHARACTER VARYING(12) NOT NULL,
  titre CHARACTER VARYING(255),
  description CHARACTER VARYING(255),
  departement CHARACTER VARYING(100) NOT NULL,
  CONSTRAINT pk_ue PRIMARY KEY (code),
  CONSTRAINT fk_ue_dpt FOREIGN KEY (departement)
      REFERENCES departement (nom) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ue OWNER TO etudiant;
 
-- Table: enseignant
 
-- DROP TABLE enseignant;
 
CREATE TABLE enseignant
(
  nss CHARACTER(15) NOT NULL,
  nom CHARACTER VARYING(255) NOT NULL,
  prenom CHARACTER VARYING(255) NOT NULL,
  departement CHARACTER VARYING(100) NOT NULL,
  CONSTRAINT pk_enseignant PRIMARY KEY (nss),
  CONSTRAINT fk_ens_dpt FOREIGN KEY (departement)
      REFERENCES departement (nom) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE enseignant OWNER TO etudiant;
 
-- Table: enseigne
 
-- DROP TABLE enseigne;
 
CREATE TABLE enseigne
(
  ue CHARACTER VARYING(12) NOT NULL,
  enseignant CHARACTER(15) NOT NULL,
  semestre CHARACTER(5) NOT NULL,
  CONSTRAINT pk_enseigne PRIMARY KEY (ue, enseignant, semestre),
  CONSTRAINT fk_enseigne_enseignant FOREIGN KEY (enseignant)
      REFERENCES enseignant (nss) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk_enseigne_ue FOREIGN KEY (ue)
      REFERENCES ue (code) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE enseigne OWNER TO etudiant;
 
-- Table: etudiant
 
-- DROP TABLE etudiant;
 
CREATE TABLE etudiant
(
  num INTEGER NOT NULL,
  nom CHARACTER VARYING(255) NOT NULL,
  prenom CHARACTER VARYING(255) NOT NULL,
  CONSTRAINT pk_etudiant PRIMARY KEY (num)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE etudiant OWNER TO etudiant;
 
-- Table: inscription
 
-- DROP TABLE inscription;
 
CREATE TABLE inscription
(
  ue CHARACTER VARYING(12) NOT NULL,
  etudiant INTEGER NOT NULL,
  semestre CHARACTER(5) NOT NULL,
  CONSTRAINT pk_inscription PRIMARY KEY (ue, etudiant, semestre),
  CONSTRAINT fk_inscription_etudiant FOREIGN KEY (etudiant)
      REFERENCES etudiant (num) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk_inscription_ue FOREIGN KEY (ue)
      REFERENCES ue (code) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE inscription OWNER TO etudiant;
 
-- Table: note
 
-- DROP TABLE note;
 
CREATE TABLE note
(
  ue CHARACTER VARYING(12) NOT NULL,
  etudiant INTEGER NOT NULL,
  semestre CHARACTER(5) NOT NULL,
  numero INTEGER NOT NULL,
  valeur DOUBLE PRECISION NOT NULL,
  CONSTRAINT pk_note PRIMARY KEY (ue, etudiant, semestre, numero),
  CONSTRAINT fk_note_inscription FOREIGN KEY (ue, etudiant, semestre)
      REFERENCES inscription (ue, etudiant, semestre) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE note OWNER TO etudiant;

Utiliser le script ci-dessus pour créer ces tables dans le schéma public de la base postgres du serveur postgresql installé sur votre machine (rappel base: postgres, login: etudiant, mdp: etudiant)

Projet embryonnaire

Maven est un utilitaire de compilation/exécution/test de projet Java qui sera utilisé dans le cadre des TP de l'UE. Configurer Maven comme indiqué dans l'aide.

Télécharger et décompresser le projet de base: bdav-tp-orm-base.zip, ou mieux, cloner le dépôt créé mardi matin.

hg clone https://forge.univ-lyon1.fr/hg/mif18-tp-base

Un projet Maven possède deux répertoires de sources: src/main et src/test. Le premier contient les classes “métier” alors que le second ne contient que le code de test.

Dans Eclipse, il faut importer le projet en utilisant Import existing maven project.

Le fichier pom.xml contient les dépendances sur les bibliothèques nécessaires au TP.

Le fichier src/main/resources/META-INF/persistence.xml contient les informations pour mettre en place le cadre de persistence:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
   version="1.0">
    <persistence-unit name="pu" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="validate"/>
            <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
            <property name="hibernate.connection.username" value="etudiant"/> 
            <property name="hibernate.connection.password" value="etudiant"/> 
            <property name="hibernate.connection.url" value="jdbc:postgresql:postgres"/> 
        </properties>
    </persistence-unit>
</persistence>

Si la connection de fonctionne pas, changer mdpetu en etudiant.

Travail demandé

  1. Concevoir un modèle objet correspondant au modèle relationnel fourni et créer des classes Java correspondantes.
  2. Annoter les classes via des annotations du package javax.persistence, afin d'établir les liens entre le modèle relationnel et votre modèle objet.

Remarques additionnelles

Tester le mapping

Le mapping relationnel objet peut être tester à travers le TestCase JUnit suivant:

package bdav.tporm;
 
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
 
import junit.framework.TestCase;
 
public class ConfigurationTest extends TestCase {
 
	public void testEntityManager() {
		EntityManager em = Persistence.createEntityManagerFactory("pu").createEntityManager();
		em.getTransaction().begin();
		em.getTransaction().commit();
                em.close();
	}
 
}

Cette classe est à placer dans le répertoire src/test/java/bdav/tporm. Elle est exécutable directement comme test JUnit dans Eclipse ou Netbeans.

Divers

  • Lorsqu’une entité/classe possède un identifiant portant sur plusieurs attributs, il faut créer une classe spécifique (qui n'est pas une entité) pour regrouper ces champs, et utiliser un champ de cette classe en lieu et place du groupe de champs servant d'identifiants dans votre modèle objet. Voir @Id, @IdClass.
  • Lorsque certaines tables ne correspondent pas nécessairement à une entité, il est possible d'utiliser les annotations @Embedded et @Embeddable.
  • Les colonnes de type xml peuvent être mise en correspondance avec des colonnes de type String
  • Changer hibernate.hbm2ddl.auto de validate à update permet au framework de modifier le schéma relationnel. Cela peut être utile pour comprendre à quoi correspond le mapping en cours de développement, mais cela écrase le schéma de l'énoncé. A la fin du TP, le mapping doit fonctionner avec le schéma de fourni plus haut. En cas d'impossibilité, justifier les différences dans des commentaires appropriés dans les classes Java.
1)
jusqu'à ce qu'une solution viable puisse être proposée pour le mapping des types hibernate en Postgresql
2)
un role de connection etudiant ordinaire doit suffire