Ce site met a disposition le build journalier de la traduction francaise du Maven: The Definitive Guide
Consultez :
  • Les documents de reference sur le projet original
  • Les sources de la traduction fr sur GitHub
  • maven


    7.3. Le module simple-model

    La première chose dont ont besoin la plupart des projets d'entreprise est un modèle objet. Un modèle objet rassemble la liste des principaux objets du domaine d'un système. Par exemple, un système bancaire pourrait avoir un modèle objet qui se compose des objets suivants : Compte, Client et Transaction. De la même manière, un système publiant des résultats sportifs pourrait contenir des objets Equipe et Match. Quoique vous fassiez, il est probable que vous ayez intégré les concepts de votre système dans un modèle objet. C'est pratique courante dans les projets Maven de séparer ce type de projet et de le référencer dans le reste du projet. Dans notre système, nous transformons chaque requête du flux Yahoo! Météo dans un objet Weather qui référence quatre autres objets. La direction, l'effet de froid relatif et la vitesse du vent sont stockées dans un objet Wind. Les données de localisation telles que le code postal, la ville, la région et le pays sont stockées dans la classe Location. Les conditions atmosphériques telles que l'humidité, la visibilité, la pression barométrique et la tendance sont conservées dans une classe Atmosphere. Enfin, la description textuelle des conditions, la température et la date de l'observation sont conservées dans une classe Condition.

    Modèle objet pour les données météo

    Figure 7.2. Modèle objet pour les données météo


    Le fichier pom.xml de ce modèle objet contient une dépendance qui nécessite une explication. Notre modèle objet est annoté avec Hibernate Annotations. Celles-ci sont utilisées pour associer ce modèle aux tables de la base de données relationnelle. Cette dépendance est org.hibernate:hibernate-annotations:3.3.0.ga. Regardons le pom.xml affiché dans l'Exemple 7.2, « POM du module simple-model », ainsi que les quelques exemples d'utilisation de ces annotations.

    Exemple 7.2. POM du module simple-model

    <project xmlns="http://maven.apache.org/POM/4.0.0" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                          http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>org.sonatype.mavenbook.multispring</groupId>
        <artifactId>simple-parent</artifactId>
        <version>1.0</version>
      </parent>
      <artifactId>simple-model</artifactId>
      <packaging>jar</packaging>
    
      <name>Simple Object Model</name>
    
      <dependencies>
        <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-annotations</artifactId>
          <version>3.3.0.ga</version>
        </dependency>
        <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-commons-annotations</artifactId>
          <version>3.3.0.ga</version>
        </dependency>
      </dependencies>
    </project>
    

    Dans le dossier src/main/java/org/sonatype/mavenbook/weather/model se trouve le fichier Weather.java. Celui-ci contient l'objet Weather annoté. Il s'agit d'un simple Java bean. Cela veut dire qu'il contient des variables d'instance privées comme id, location, condition, wind, atmosphere et date. Celles-ci sont exposées par l'intermédiaire d'accesseurs publiques en suivant ce pattern : une propriété nommée name disposera d'un getter public sans argument nommé getName(), et d'un setter prenant en paramètre un argument nommé setName(String name). Si nous montrons le getter et le setter de la propriété id, nous avons omis volontairement la plupart des getters et des setters des autres propriétés afin de sauver quelques arbres. Consultez l'Exemple 7.3, « Objet Weather annoté ».


    Exemple 7.3. Objet Weather annoté

    package org.sonatype.mavenbook.weather.model;
    
    import javax.persistence.*;
    
    import java.util.Date;
    
    @Entity
    @NamedQueries({
      @NamedQuery(name="Weather.byLocation", 
                  query="from Weather w where w.location = :location")
    })
    public class Weather {
    
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;
    
        @ManyToOne(cascade=CascadeType.ALL)
        private Location location;
    
        @OneToOne(mappedBy="weather",cascade=CascadeType.ALL)
        private Condition condition;
    
        @OneToOne(mappedBy="weather",cascade=CascadeType.ALL)
        private Wind wind;
    
        @OneToOne(mappedBy="weather",cascade=CascadeType.ALL)
        private Atmosphere atmosphere;
    
        private Date date;
        
        public Weather() {}
    
        public Integer getId() { return id; }
        public void setId(Integer id) { this.id = id; }
    
        // Nous avons omis les autres getter et setter...
    }
    

    La classe Weather utilise des annotations qui permettent de guider Hibernate pour associer cet objet à une table de la base de données relationnelle. Bien qu'une explication détaillée des annotations Hibernate dépasse les limites de ce chapitre, en voici quelques grandes lignes. L'annotation @Entity marque la classe comme entité persistante. Nous avons omis l'annotation @Table sur cette classe, ainsi, Hibernate va utiliser le nom de la classe comme nom de table. L'annotation @NamedQueries définit une requête qui sera utilisée par le WeatherDAO dans le module simple-persist. Le langage utilisé dans la requête de l'annotation @NamedQuery est écrit en HQL (Hibernate Query Language). Chaque champ de la classe est annoté par des annotations définissant le type des différentes colonnes à associer ainsi que les relations impliquées sur celles-ci :

    Id

    La propriété id est annotée avec @Id. Cette annotation marque ce champ comme propriété contenant la clé primaire de la table de base de données. L'annotation @GeneratedValue permet de contrôler comment les nouvelles valeurs de la clé primaire sont générées. Dans le cas de notre propriété id, nous utilisons la valeur IDENTITY de l'énumération GenerationType qui permet d'utiliser la génération d'identité fournie par la base de données sous-jacente.

    Location

    Chaque instance de la classe Weather contient un objet Location. Ce dernier représente un code postal. Son annotation @ManyToOne vous assure que tous les objets Weather qui possèdent la même Location pointent effectivement vers les mêmes instances. L'attribut cascade de l'annotation @ManyToOne permet d'assurer qu'un objet Location soit enregistré à chaque sauvegarde d'un objet Weather.

    Condition, Wind, Atmosphere

    Chacun de ces objets est mappé avec une annotation @OneToOne dont la propriété cascade est à CascadeType.ALL. Cette propriété signifie qu'à chaque sauvegarde d'un objet Weather une ligne sera créée dans chacune des tables suivantes : Condition, Wind et Atmosphere.

    Date

    Le champ Date n'est pas annoté. Cela signifie qu'Hibernate va utiliser la configuration par défaut pour son mapping. Le nom de la colonne sera date et possédera le type timestamp approprié pour un objet Date.

    Note

    Si vous désirez omettre une propriété du mapping, vous pouvez annoter celle-ci avec @Transient.

    Ensuite, jetons un coup d'oeil à un second objet du modèle, Condition, affiché dans l'Exemple 7.4, « Classe Condition du module simple-model ». Cette classe se trouve également dans le dossier src/main/java/org/sonatype/mavenbook/weather/model.

    Exemple 7.4. Classe Condition du module simple-model

    package org.sonatype.mavenbook.weather.model;
    
    import javax.persistence.*;
    
    @Entity
    public class Condition {
    
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;
    
        private String text;
        private String code;
        private String temp;
        private String date;
    
        @OneToOne(cascade=CascadeType.ALL)
        @JoinColumn(name="weather_id", nullable=false)
        private Weather weather;
    
        public Condition() {}
    
        public Integer getId() { return id; }
        public void setId(Integer id) { this.id = id; }
    
        // Nous avons omis les autres getter et setter...
    }

    La classe Condition ressemble à la classe Weather. Elle est annotée avec @Entity et possède les mêmes annotations sur la propriété id. Les champs text, code, temp et date ne possèdent pas d'annotation et restent donc liés à la base de données selon la configuration par défaut. La propriété weather est annotée avec @OneToOne et @JoinColumn qui permettent de référencer l'objet Weather associé via la clé étrangère weather_id.