IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Annotations ManyToMany - 1 classe 2 tables - infos dans table de jointure


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 25
    Par défaut Annotations ManyToMany - 1 classe 2 tables - infos dans table de jointure
    Bonjour,

    Voici mon problème:
    J'ai une relation ManyToMany unidirectionnelle entre une classe (exemple) Garage et une classe Voiture.
    Garage contient donc une Liste de Voitures

    En DB, c'est traduit par une table Garage, une table Voiture et une joinTable Garage_Voiture.

    Jusque là, tout va bien.
    Maintenant ça se complique, Garage contient donc plusieurs instances de Voiture, mais certaines propriétés de Voiture (comme la couleur) varient en fonction du Garage qui le contient...

    concrètement, en DB, ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Garage	Garage_Voiture	Voiture
    ------  -------------- -----------
    ID	ID_Garage	ID
    nom	ID_Voiture	marque
    	couleurVoiture

    Mon problème: Comment mapper ça dans mes classes avec les annotations?
    "couleurVoiture" étant bien sûr un attribut de la classe Voiture


    Voici ce à quoi ressemblent mes classes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @Entity
    @Table(name="Garage")
    public class Garage implements Serializable
    {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        @Column(name="ID")
        private Long id;
     
        @Column(name="nom")
        private String nom;
     
        @ManyToMany
        @JoinTable(name="Garage_Voiture",
            joinColumns=@JoinColumn(name="Garage_ID"),
            inverseJoinColumns=@JoinColumn(name="Voiture_ID"))
        private List<Voiture> listVoitures;
     
        ...
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    @Entity
    @Table(name="Voiture")
    public class Voiture implements Serializable
    {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        @Column(name="ID")
        private Long id;
     
        @Column(name="marque")
        private String marque;
     
        @Column(name="couleurVoiture")
        private String couleurVoiture;
     
        ...
    }
    Grand merci pour le coup de pouce...

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Avril 2007
    Messages : 35
    Par défaut
    Pour faire un mapping de ce type avec JPA, il faut créer une entité intermédiaire (comme il y a une table intermédiaire en base en fait...)

    garage - lien_garage_voiture - voiture
    avec le mapping suivant :
    OneToMany - ManyToOne - OneToMany

    Ca donne donc qqch comme ça :

    Garage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    @Entity
    @Table(name = "garage")
    public class Garage 
    {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        protected Integer id;
        @OneToMany(mappedBy = "garage")
        private List<LienGarageVoiture> lien_voitures;
    }
    ...
    LienGarageVoiture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    @Entity
    @Table(name = "garage_voiture")
    public class LienGarageVoiture
    {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        protected Integer id;
     
        @Column(name = "COULEUR")
        private String couleur;
     
        @ManyToOne
        @PrimaryKeyJoinColumn(name = "GARAGEID", referencedColumnName = "ID")
        private Garage garage;
     
        @ManyToOne
        @PrimaryKeyJoinColumn(name = "VOITUREID", referencedColumnName = "ID")
        private Voiture voiture;
    Voiture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    @Entity
    public class Voiture
    {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        protected Integer id;
        @OneToMany(mappedBy = "voiture")
        private List<LienGarageVoiture> lien_garages;
    Note : ceci est un exemple, à adapter bien sur...

    Par contre, est-il pertinent de mettre l'attribut "couleur_voiture" dans une table de lien telle que celle ci ?
    Parce que d'après ce que je vois, la couleur d'une voiture est un attribut de la voiture, et ne dépend donc pas du garage (et donc, pas d'attribut de lien...).
    D'un point de vue purement logique, une voiture n'a qu'une seule et unique couleur. Une même voiture physique ne va pas changer de couleur en fonction du garage ou elle se trouve, et ne peut pas se trouver dans plusieurs garages en même temps. Par contre, plusieurs voitures de même modèle peuvent exister...

    Bref, voilà une méthode pour faire ce type de mapping et une petite question sur la validité de la conception.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 25
    Par défaut
    Bonjour, merci pour cette réponse très rapide.

    "Garage" et "Voiture" étaient des mauvais exemples.
    Remplaçons "Garage" par "Collection" et "Voiture" par "Objet" (d'art).

    Une "Collection" contient X "Objets" et admettons qu'un "Objet" puisse apparternir à X "Collections"

    Un "Objet" dispose des attributs invariables suivants:

    ID
    code
    dateCreation
    valeur
    propriétaire

    Chaque "Objet" dispose d'autres attributs, qui varient en fonction de la "Collection" dont il fait partie (ces deux attributs d'un Objet dépendent donc bien de l'association entre un Objet et une Collection).

    dateDébutDuPret
    dateFinDuPret


    Ce qui veut dire que, si ces attributs variables se trouvent dans ma table "Objet" et pas dans ma table d'association "Collection_Objet", je vais avoir de la redondance au niveau des infos fixes dans "Objet".

    --> Si un "Objet" se retrouve dans 10 Collections, je vais donc avoir 10 records dans ma table "Objet", avec 10 fois le même "code", 10 fois la même "dateCreation" et 10 fois la même "valeur"... .
    --> Ce qui veut dire qu'à partir de ce moment, je ne suis déjà plus en Deuxième forme normale.

    Si je place les attributs variables d'un "Objet" dans la table d'association "Collection_Objet", alors je garde 1 seule ligne par "Objet" dans la table "Objet", et ces valeurs fixes ne sont pas liées à l'association "Collection_Objet"
    --> je suis en 2eme forme normale, pas de redondance d'infos.

    Je devrais donc avoir au niveau de mes tables:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Collection  Collection_Objet  Objet
    ---------  ----------------- --------
    ID          ID_Collection    ID			
    nom         ID_Objet         code
                dateDébutDuPret  dateCreation
                dateFinDuPret    valeur
                                 propriétaire

    Et au niveau de mes classes, je voudrais avoir ceci:
    Avec dans chaque Objet, les attribut dateDébutDuPret et dateFinDuPret, puisque ces dates sont bien liées à l'Objet, chaque Objet étant instancié dans chaque collection dont il fait partie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class Collection
    {
    	Long ID;
    	String nom;
     
    	List<Objet> listObjets;
    	...
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class Objet
    {
    	Long ID;
    	String code;
    	Date dateCreation;
    	Double valeur;
    	String propriétaire;
     
    	Date dateDébutDuPret;
    	Date dateFinDuPret;
    	...
    }
    Je ne veux donc pas avoir de classe d'association intermédiaire "Collection_Objet", ça n'aurait pas de sens en terme de modélisation objet.

    J'espère que mon exemple est un peu plus clair.

    Est-ce possible ? Comment faire dans ce cas ?

    Grand merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 08/10/2012, 15h46
  2. Domain class perd des infos dans une liste
    Par jackRackham dans le forum Grails
    Réponses: 8
    Dernier message: 27/09/2011, 10h26
  3. transfert table dynamique dans table interne
    Par julie31 dans le forum Autres ERP
    Réponses: 0
    Dernier message: 07/07/2010, 10h55
  4. [WD12] Colonne de table accessible dans table en affichage seul
    Par Romanops dans le forum WinDev
    Réponses: 3
    Dernier message: 09/10/2009, 12h10
  5. Recherche dans table MySQL dans une fonction js
    Par dodo91 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 20/05/2009, 11h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo