26.  Les services web et Eclipse Partie 6 : le développement d'applications mobiles Imprimer Sommaire Consulter avec table des matières Développons en Java avec Eclipse   v 0.80  
Copyright (C) 2003-2007 Jean-Michel DOUDOUX   

 

27. JPA et Eclipse

 

chapitre 2 7

 

 

 

27.1. Dali

Dali est un plug-in proposant de fournir des outils pour faciliter le mapping objet/relationnel.

Dali est un sous projet du projet WTP dont le but est de faciliter la mise en oeuvre de l'API JPA (Java Persistence API) définie par la JSR 220.

La page officiel du projet est l'url : http://www.eclipse.org/dali.

Les versions utilisées dans cette section sont :

Eclipse 3.2.1
WTP 1.5.1
Dali 0.5
MySQL 4.1
API JPA  Implémentation de référence (toplink-essentials.jar) fournie avec GlassFish

La version utilisée du plug-in dans cette section est en cours développement mais elle propose déjà des fonctionnalités intéressantes.

 

27.1.1. La création et la configuration d'un nouveau projet

Il faut ouvrir la perspective Java Perspective : sélectionnez l'option « Fenêtre / ouverture la perspective » du menu principal.

Sélectionnez « Java Persistence » et cliquez sur le bouton « OK » pour ouvrir la perspective.

Créez un nouveau projet de type Java associé à un JRE 1.5 minimum.

Il faut ajouter le support de l'API Java Persistence au projet.

Sélectionnez le projet dans l'explorateur de projet et utiliser l'option Java Persistence / Add Java Persistence » : une boîte de dialogue perme de saisir les informations requises.

Cliquez sur le lien « Add connections »

Saisissez les informations concernant la base de données et sa connexion.

Cliquez sur le bouton « Tester la connexion »

Si la base de données n'est pas trouvée, un message est affiché :

Si la base de données est trouvée, un message d'information est affiché

Cliquez sur le bouton « OK » puis sur le bouton « Terminer »

Cliquez sur le bouton « Configure the project build path »

Cliquez sur l'onglet « Bibliothèques », puis sur le bouton « Ajouter des fichiers jar externes »

Sélectionnez le fichier toplink-essentials.jar, puis cliquez sur le bouton « Ouvrir » et sur le bouton « OK ».

Sélectionnez le schéma de la base de données (dans le cas de MySQL, c'est la base de données elle-même)

Saisissez le nom de la classe du Provider de Persistence : oracle.toplink.essentials.PersistenceProvider et le nom de l'unité de persistence puis cliquez sur le bouton « Terminer ».

Le fichier persistence.xml est créé dans le répertoire META-INF

Ce fichier xml est le fichier de configuration de l'API JPA.

La connexion à la base de données est affichée dans la vue « Explorateur de base de données ».

 

27.1.2. Ajouter une entité persistante

Créez une nouvelle entité de type « Java Persistence / Entity »

Cliquez sur le bouton « Suivant »

Saisissez le nom du package et le nom de la classe puis cliquez sur le bouton « Terminer ».

La classe est générée et son contenu est ouvert dans un éditeur.

La classe est marquée avec l'annotation @Entity : elle est en erreur car aucun champ de la classe n'est marqué avec l'annotation @Id qui est obligatoire.

La vue « Persistence Outline » affiche la nouvelle entity créée.

La vue « Persistence properties » affiche les propriétés de cet élément.

Cette vue indique que l'entité est mappée sur le table Personne.

Il faut ajouter les champs dans l'entité :

La vue « Persistence outline » affiche les champs ajoutés

Il faut réaliser le mapping entre les champs de l'entité et les champs de la table

Dans la vue « Persistence outline », sélectionnez le champ id.

Modifiez le champ « Map As » en sélectionnant le type « Id » : le code de la classe est modifié pour ajouter l'annotation @Id sur le champ.

L'icône du champ est aussi modifié dans la vue « Persistence outline » pour indiquer que ce champ est la clé.

Sélectionnez le type « Basic » pour les deux autres champs. Comme le nom des champs correspond exactement dans la table et dans la classe, le mapping est automatique.

L'entité ainsi modifiée est la suivante

L'éditeur affiche les erreurs de mapping si certaines sont détectées.

 

27.1.3. Exemple d'utilisation de l'API

Il faut rajouter dans le classpath de l'application la bibliothèque du pilote JDBC (dans cet exemple c'est la base de données MySQL qui est utilisée : le fichier mysql-connector-java-3.1.10-bin.jar est donc ajouté au classpath du projet).

Il faut enrichir le fichier persistence.xml avec les propriétés de connexion à la base de données.

Exemple :
    <?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"
      version="1.0"    
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
      http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">    
      <persistence-unit name="test_dali">    
        <provider>    
          oracle.toplink.essentials.PersistenceProvider    
        </provider>    
        <class>com.jmdoudoux.test.dali.Personne</class>    
        <properties>    
          <property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver" />    
          <property name="toplink.jdbc.url" value="jdbc:mysql://localhost/test" />    
          <property name="toplink.jdbc.user" value="root" />    
          <property name="toplink.jdbc.password" value="" />    
          <property name="toplink.logging.level" value="INFO" />    
        </properties>    
      </persistence-unit>    
    </persistence>

Il faut enfin écrire le code qui va utiliser l'API JPA et les différentes entités de mapping générées.

Exemple : obtenir la personne dont l'identifiant vaut 1

Exemple :
package com.jmdoudoux.test.dali;    

import javax.persistence.Persistence;    
import javax.persistence.EntityManagerFactory;    
import javax.persistence.EntityManager;    

public class TestDali {    

  public static void main(String[]argv) {    
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("test_dali");    
    EntityManager em = emf.createEntityManager();    
    Personne personne = em.find(Personne.class, 1l);    
    System.out.println("Personne.nom="+personne.getNom());    
    em.close();    
    emf.close();    
  }    
}

Résultat d'exécution :
         
    [TopLink Info]: 2006.11.06
  06:01:18.134--ServerSession(25378506)--TopLink, version:
  Oracle TopLink Essentials - 2006.4 (Build 060412)    
    [TopLink Info]: 2006.11.06
  06:01:19.757--ServerSession(25378506)--file:/C:/Documents%20and%20Settings
  /jumbo/workspace/TestDali/bin-test_dali
  login successful    
    Personne.nom=nom1    
    [TopLink Info]: 2006.11.06
  06:01:20.117--ServerSession(25378506)--file:/C:/Documents%20and%20Settings
  /jumbo/workspace/TestDali/bin-test_dali
  logout successful

 

27.1.4. Connexion à la base de données.

Avant de pouvoir utiliser les fonctionnalités du plug-in, il est nécessaire d'être connecté à la base de données afin de pouvoir contrôles les informations de mapping.

Il est possible de le faire dans les propriétés du projet.

Sélectionnez “Java Persistence” et cliquez sur le bouton “Reconnect”.

Il est aussi possible d'utiliser la vue « Explorateur de base de données ».

Sélectionnez la connexion et cliquez sur l'option “Reconnecter” du menu contextuel

Une boîte de dialogue permet de saisir le login et le mot de passe de connexion.

Si la connexion échoue alors un message d'erreur affiche la pile d'appel des exceptions

Si la connexion réussie, la base de données est affichée avec une petite icône verte et il est possible de parcourir l'arborescence des éléments qui la compose.

 

27.1.5. La génération des entités à partir de la base de données

Le plug-in propose une fonctionnalité pour générer automatiquement les entités à par des tables d'une base de données connectées.

Sélectionnez le projet et utilisez l'option Java « Java Persistence/Generate entities »

Saisissez le nom du package, sélectionnez les tables concernées et cliquez sur le bouton « Terminer ».

Si une classe correspondant à une entité existante, alors un message de confirmation est affiché :

Les différentes classes des entités sont générées.

 

27.1.6. L'éditeur du fichier persistence.xml

Dali  propose un éditeur dédié à la modification du fichier persistence.xml. C'est l'éditeur par défaut de ce fichier. Il propose deux onglets : Conception et Source

La modification du fichier est facilitée par l'éditeur qui intègre le schéma du document XML.

 

27.1.7. La synchronisation des classes

Dans l'explorateur de packages, il faut sélectionner le fichier persistence.xml et utiliser l'option « Persistence / Synchronize classes » du menu contextuel.

Chaque nouvelle entité définie dans les sources est automatiquement ajoutée dans un tag <class> du fichier persistence.xml.

Le travail de synchronisation est effectué en tache de fond.

 

27.1.8. Transformer une classe existante  en entité

Il est possible de transformer une classe existante en Entity.

Exemple :

Sélectionnez la classe (ne sélectionnez pas le fichier .java mais la classe directement) dans l'explorateur de packages et utiliser l'option « Persistence / Make Java Persistence Entity ».

La clause import nécessaire et l'annotation « Entity » sont ajoutées :

Dans l'éditeur de code, sélectionnez la classe puis affichez la vue « Persistence Properties »

Dans la liste déroulante « Map As » sélectionnez « Entity »

La boîte de dialogue s'enrichie avec les propriétés relative au type Entity.

Dans la liste déroulante Table, sélectionnez la table infopersonne

Le code de l'entité est modifié

 

27.1.9. La création d'une association 1-1

L'exemple de cette section va utiliser les tables ci dessous

La table « personne » contient les données suivantes :

La table « infopersonne » contient les données suivantes :

Il faut mettre en place l'association en modifiant la classe Personne

Exemple :
package com.jmdoudoux.test.dali;
    
import javax.persistence.Entity;    
import javax.persistence.Id;    
import javax.persistence.Basic;    
import javax.persistence.Table;    

@Entity    
@Table(name="personne")    
public class Personne {    

  @Id    
  private Long idPersonne;    

  @Basic    
  private String nomPersonne;    

  @Basic    
  private String prenomPersonne;    
  private InfoPersonne idInfoPersonne;    
}

Dans l'éditeur de code, sélectionnez le champ idInfoPersonne

Dans la vue « Persistence Properties », l'onglet « Join columns » permet de modifier les options de la jointure

Cochez la case « Override Default »

Sélectionnez la ligne dans la liste et cliquez sur le bouton « Edit » pour ouvrir la boîte de dialogue « Edit Join Column »

Dans la liste déroulante Name, sélectionnez le champ idInfoPersonne

Cliquez sur le bouton « OK » pour modifier le code de l'entité

Exemple :
  @OneToOne    
  @JoinColumn(name="idInfoPersonne", referencedColumnName = "idInfoPersonne")    
     private     InfoPersonne idInfoPersonne;

Sources complets de l'exemple :

Le fichier Persistence.xml :
<?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" version="1.0"    
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">    
  <persistence-unit name="test_dali">    
    <provider>    
      oracle.toplink.essentials.PersistenceProvider    
    </provider>    
    <class>com.jmdoudoux.test.dali.InfoPersonne</class>    
    <class>com.jmdoudoux.test.dali.Personne</class>    
    <properties>    
      <property name="toplink.jdbc.driver"    
        value="com.mysql.jdbc.Driver" />    
      <property name="toplink.jdbc.url"    
        value="jdbc:mysql://localhost/test" />    
      <property name="toplink.jdbc.user" value="root" />    
      <property name="toplink.jdbc.password" value="" />    
      <property name="toplink.logging.level" value="INFO" />    
    </properties>    
  </persistence-unit>    
</persistence>

Le fichier InfoPersonne.java :
package com.jmdoudoux.test.dali;

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Basic;

@Entity
@Table(name="infopersonne")
public class InfoPersonne {

  @Id
  @Column(name="idInfoPersonne")
  private long idInfoPersonne;

  @Basic
  private String commentaires;

  public String getCommentaires() {
    return commentaires;
  }

  public void setCommentaires(String commentaires) {
    this.commentaires = commentaires;
  }

  public long getIdInfoPersonne() {
    return idInfoPersonne;
  }

  public void setIdInfoPersonne(long idInfoPersonne) {
    this.idInfoPersonne = idInfoPersonne;
  }
}

Le fichier Personne.java
package com.jmdoudoux.test.dali;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Basic;
import javax.persistence.Table;
import javax.persistence.OneToOne;
import javax.persistence.JoinColumn;

@Entity
@Table(name="personne")
public class Personne {

  @Id
  private Long idPersonne;

  @Basic
  private String nomPersonne;

  @Basic
  private String prenomPersonne;

  @OneToOne
  @JoinColumn(name="idInfoPersonne", referencedColumnName = "idInfoPersonne")
  private InfoPersonne idInfoPersonne;  

  public Long getId() {
    return idPersonne;
  }

  public void setId(Long id) {
    this.idPersonne = id;
  }

  public String getNom() {
    return nomPersonne;
  }

  public void setNom(String nom) {
    this.nomPersonne = nom;
  }

  public String getPrenom() {
    return prenomPersonne;
  }

  public void setPrenom(String prenom) {
    this.prenomPersonne = prenom;
  }

  public InfoPersonne getIdInfoPersonne() {
    return idInfoPersonne;
  }

  public void setIdInfoPersonne(InfoPersonne idInfoPersonne) {
    this.idInfoPersonne = idInfoPersonne;
  }
}

Le fichier TestDali.java
package com.jmdoudoux.test.dali;
  
import javax.persistence.Persistence;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityManager;
 
public class TestDali {

  public static void main(String[]argv) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("test_dali");
    EntityManager em = emf.createEntityManager();
    Personne personne = em.find(Personne.class, 1l);
    System.out.println("Personne.nom="+personne.getNom());
    System.out.println("commentaires = "
      +personne.getIdInfoPersonne().getCommentaires());
    em.close();
    emf.close();
  }
}

Résultat d'exécution :
  [TopLink Info]: 2006.11.09
    07:06:29.267--ServerSession(31999426)--TopLink, version:
    Oracle TopLink Essentials - 2006.4 (Build 060412)
  [TopLink Info]: 2006.11.09
    07:06:30.679--ServerSession(31999426)--file:/C:/Documents%20and%20Settings
    /jumbo/workspace/TestDali/bin-test_dali
    login successful
  Personne.nom=nom1
  commentaires = commentaires de test
  [TopLink Info]: 2006.11.09 07:06:31.009--ServerSession(31999426)--file:/C:
    /Documents%20and%20Settings
    /jumbo/workspace/TestDali/bin-test_dali
    logout successful

L'exemple fonctionne correctement car la clé étrangère existe. Il est nécessaire de gérer le cas si la clé n'existe pas.

Exemple : demander les informations de la personne ayant pour id 2
  ...
         Personne personne = em.find(Personne.class, 2l);
  ...

Exemple :
Résultat :
  [TopLink Info]: 2006.11.10
    05:17:15.523--ServerSession(31999426)--TopLink, version:
    Oracle TopLink Essentials - 2006.4 (Build 060412)
  [TopLink Info]: 2006.11.10
    05:17:16.895--ServerSession(31999426)--file:/C:/Documents%20and%20Settings
    /jumbo/workspace/TestDali/bin-test_dali
    login successful
  Personne.nom=nom2
  Exception in thread "main" java.lang.NullPointerException
        at com.jmdoudoux.test.dali.TestDali.main(TestDali.java:16)

Il suffit de tester si la clé étrangère est différente de null.

Exemple :
    Personne personne = em.find(Personne.class, 2l);
    System.out.println("Personne.nom=" + personne.getNom());
    if (personne.getIdInfoPersonne() != null) {
          System.out.println("commentaires = "
                     + personne.getIdInfoPersonne().getCommentaires());
    }

 


  26.  Les services web et Eclipse Partie 6 : le développement d'applications mobiles Imprimer Sommaire Consulter avec table des matières Développons en Java avec Eclipse   v 0.80  
Copyright (C) 2003-2007 Jean-Michel DOUDOUX