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 :

Mapping de map un peu complexe


Sujet :

Hibernate Java

  1. #1
    Membre du Club
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Directeur des systèmes d'information

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 64
    Points
    64
    Par défaut Mapping de map un peu complexe
    Bonjour.

    J'ai trois objets : Table, Objectif, Projet et trois tables:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Table ( id, nom, ...)
    Objectif (id, #idTable=>Table.id, #idProjet=>Projet.id, ...)
    Projet (id, nomProjet, ...)
    Un objectif est associé à une table.
    Un objectif n'appartient qu'a un seul projet.
    Un projet n'a qu'un objectif par table.

    Et dans la classe projet j'ai donc tout logiquement :
    Map<Table, Objectif>

    Je ne vois pas comment faire le mapping vu que en java c'est Projet->Objectif et en BDD : Objectif->Java

    Avez-vous des idées ?

    Merci d'avance.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 69
    Points : 76
    Points
    76
    Par défaut
    Hello,

    Peut-être je comprend mal ton problème mais je ne pense pas que tu doives définir une Map dans ton Projet.

    J'ai l'impression que ceci est la conception (faut rajouter les getters & setters) liée à ton problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class Table {
    	long id;
    	String nom;
    	Set<Objectif> objectifs;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class Projet {
    	long id;
    	String nomProjet;
    	Set<Objectif> objectifs;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class Objectif {
    	private long id;
    	private Table table;
    	private Projet projet;
    }

  3. #3
    Membre du Club
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Directeur des systèmes d'information

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 64
    Points
    64
    Par défaut
    Merci pour cette réponse.

    En fait, au niveau de la conception, je considère qu'une table n'a pas à connaître d'objectifs. Elle ne connaît personne en fait, elle est autonome.

    (En gros, le but de l'application est de compter le nombre d'enregistrements pour chaque table qui vont être réalisés dans le cadre d'un projet)

    D'une manière théorique pure j'ai l'association suivante :
    Le projet connait tous ses objectifs, chaque objectif est associé à une table.

    D'un point de vue pratique, j'ai besoin à partir du nom d'une table de retrouver l'objectif associé à cette table dans le cadre d'un projet.
    Donc plutôt que de faire un
    Iterator<Objectif> it = objectifs.iterator();
    boolean trouve = false;
    while (it.hasNext() && !trouve)
    {
    unObjectif = it.next();
    if (unObjectif.getTable() == maTableQueJeRecherche) trouve=true;
    }
    J'ai construit une map<Table, Objectif>
    et hop un maMap.get(Table) et c'est torché.

    D'après ce que j'ai pu lire sur hibernate et co. mes objets metiers ne doivent pas être dépendant de la couche de persistance. Donc j'ai tout fait en pojo et là je regarde comment je peux connecter tout ça à hibernate (et c'est vraiment pas facile :/ )

    J'ai envie de dire qu'intuitivement un criteria ferait bien l'affaire mais ça mélangerais la logique metier avec la persistance.

    Après, peut être que la map n'est pas appropriée pour ce que je veux faire ?

  4. #4
    Membre du Club
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Directeur des systèmes d'information

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 64
    Points
    64
    Par défaut
    En réfléchissant bien, je me rends compte que cette map n'a pas d'équivalent dans ma bdd.
    C'est cette distance entre ma "commodité" java et le modèle relationnelle qui pose problème.

    A part la moche boucle while je vois pas vraiment comment faire.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 69
    Points : 76
    Points
    76
    Par défaut
    Si ta cardinalité est la suivante :
    Table (0-n) - (1-1) Objectif
    Projet (0-n) - (1-1) Objectif

    Le modèle que je te soumet devrait être ok.

    Les fichiers de mapping te mèneront à avoir 3 tables. Et la table Objectif aura 2 clés étrangères (1 vers Table et 1 vers Projet).

    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
    21
     
    tables` (
      `id` bigint(20) NOT NULL auto_increment,
      `nom` varchar(255) default NULL,
      PRIMARY KEY  (`id`)
    )
     
    `projets` (
      `id` bigint(20) NOT NULL auto_increment,
      `nomProjet` varchar(255) default NULL,
      PRIMARY KEY  (`id`)
    )
     
    `objectifs` (
      `id` bigint(20) NOT NULL auto_increment,
      `table_id` bigint(20) default NULL,
      `projet_id` bigint(20) default NULL,
      PRIMARY KEY  (`id`),
      KEY `FK4D4EC737606F1336` (`projet_id`),
      KEY `FK4D4EC737F0AE427E` (`table_id`)
    )
    Après, si tu dois obtenir objectif pour une table et un projet tu peux le faire de plusieurs manière :
    1 - Tu récupère une table sur base de son nom, tu parcours les objectifs pour lesquels tu récupères le projet et tu fais un test sur celui-ci

    2 - En SQL ou HQL, tu fais une requête jointe dont l'équivalent sql serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    select ... from objectifs, tables, projets 
    where 
    objectifs.table_id=tables.id 
    and 
    objectifs.projet_id=projets.id
    and tables.name="xxx"
    and projets.name="yyy"

  6. #6
    Membre du Club
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Directeur des systèmes d'information

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 64
    Points
    64
    Par défaut
    Oui, je suis ok avec le schéma (qui est celui de mon premier post).

    Ce qui me gène maintenant, c'est dans l'implémentation de projet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Objectif projet.getObjectif(Table t)
    {
      if (t == null) throw....
      return mapObjectifsParTable.get(t);
    }
    va devenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Objectif projet.getObjectif(Table t)
    {
      if (t == null) throw
      //ta requete sql
    }
    Ce qui veux dire que projet est lié à hibernate, ce qui à ce que j'ai compris n'est pas très propre. Ou alors j'ai mal compris

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 69
    Points : 76
    Points
    76
    Par défaut
    Citation Envoyé par hpavavar Voir le message
    Ce qui veux dire que projet est lié à hibernate
    Non et heureusement.

    En fait, tes POJO restent des simples javabeans (juste des attributs et des accessseurs).

    Tu va te définir une classe de service : ObjectifManager (par exemple)

    avec une méthode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public Objectif getObjectifByTableProjet(String tableName, String ProjetName);
    Dans l'implémentation de cette classe tu récupèreras l'objectif de la manière qui tu préfères.

    Attention, dans ta classe de service il n'y a tjs pas d'implémentation hibernate. Ta classe de service utilise une classe DAO dont l'implémentation contient le code Hibernate.

    Exemple pour la solution 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    TableDao implements ITableDao {
     
    	public Table selectTableByName(String name) {
    		//IMplementation hibernate
    	}
     
    	//et tout le reste bien entendu
     
    }
    Exemple pour la solution 2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ProjetDao implements IProjetDao {
    	public Projet selectProjetByTableProjet (String tableName, String ProjetName) {
    		//IMplementation hibernate avec HQL ou SQL
    	}
     
    	//et tout le reste bien entendu
     
    }

  8. #8
    Membre du Club
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Directeur des systèmes d'information

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 64
    Points
    64
    Par défaut
    Ouf

    Mais je vois mal dans la pratique comment ça se passe.
    Imaginons, que je veuille lister tous mes projets, je fais donc :
    Set<Projet> lesProjets = ProjetManger.getTousLesProjet();

    Donc ce ProjetManager va me chercher dans la base mon ensemble de projet.
    Est-ce que après je peux toujours faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Objectif unObjectif = unProjet.getObjectifsParTable(uneTable);
    System.out.println(unObjectif.getXxx() + unObjectif.getTable().getNom())
    Ou il va falloir que je change pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Objectif unObjectif = ObjectifManager.getObjectifsParTablePourUnProjet(uneTable, unProjet);
    System.out.println(unObjectif.getXxx() + TableManager.getTablePourObjectif(unObjectif).getNom());

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 69
    Points : 76
    Points
    76
    Par défaut
    Citation Envoyé par hpavavar Voir le message
    je fais donc :
    Set<Projet> lesProjets = ProjetManger.getTousLesProjet();

    Donc ce ProjetManager va me chercher dans la base mon ensemble de projet.
    Le ProjetManager appelle la méthode du ProjetDAO qui va chercher dans la base ton ensemble de projet



    Citation Envoyé par hpavavar Voir le message
    Est-ce que après je peux toujours faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Objectif unObjectif = unProjet.getObjectifsParTable(uneTable);
    System.out.println(unObjectif.getXxx() + unObjectif.getTable().getNom())
    Ou il va falloir que je change pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Objectif unObjectif = ObjectifManager.getObjectifsParTablePourUnProjet(uneTable, unProjet);
    System.out.println(unObjectif.getXxx() + TableManager.getTablePourObjectif(unObjectif).getNom());
    Plutôt la solution 2. C'est pas vraiment à ton Pojo Projet de faire le tri des objectifs par table (bien que ce soit techniquement possible).

    Tu me suis ? On est en plein dans le modèle en couche : Des objets métiers simples (POJO), des services métiers intelligents (XXXManager ou XXXService...), des classe de persistance (XXXDao)

  10. #10
    Membre du Club
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Directeur des systèmes d'information

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 64
    Points
    64
    Par défaut
    Tu me suis ? On est en plein dans le modèle en couche : Des objets métiers simples (POJO), des services métiers intelligents (XXXManager ou XXXService...), des classe de persistance (XXXDao)Q
    Ca reste confus pour moi.

    Pour la recupération de mes projets :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Set<Projet> ProjetManager.getTousLesProjet()
    {
      return ProjetDAO.getTousLesProjets();
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Set<Projet> ProjetDAO.getTousLesProjet()
    {
      Criteria crit = getSession().createCriteria(ProjetDAO.class);
      return new HashSet<Projet>(crit.list());
    }
    J'ai l'impression que c'est ça.

    En revanche, pour la navigation dans ma collection ça me semble complexe.
    Est-ce que mon pojo projet contient toujours une collection d'objectifs ? Est-ce que j'y accède toujours directement via des getters ? Ou alors pour chaque accès faut que je passe par un gestionnaire ?
    Est-ce qu'il (projet pojo) connait son dao ?

    Merci pour ton aide.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 69
    Points : 76
    Points
    76
    Par défaut
    Citation Envoyé par hpavavar Voir le message
    J'ai l'impression que c'est ça.
    Oui

    Citation Envoyé par hpavavar Voir le message
    Est-ce que mon pojo projet contient toujours une collection d'objectifs ?
    Oui

    Citation Envoyé par hpavavar Voir le message
    Est-ce que j'y accède toujours directement via des getters ?
    Oui

    Citation Envoyé par hpavavar Voir le message
    Est-ce qu'il (projet pojo) connait son dao ?
    Non. C'est la manager qui connait le DAO.

  12. #12
    Membre du Club
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Directeur des systèmes d'information

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 64
    Points
    64
    Par défaut
    Ok, donc si je veux afficher dans une fenêtre : une liste des projet, + tableau avec Table | Objectif pour le projet selectionné, je dois faire :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    //dans la vue
    Set<Projet> lesProjets = ProjetManger.getTousLesProjet();
    ComboBox comboProjets = new .... 
    cmboProjets.setModel(lesProjets);
     
    ...
    Projet projetSelectionné = comboProjets.getSelectionné();
    Tableau objectifsEtTables = new ... ;
    objectifsEtTables.setModel( ObjectifManager.getObjectifs(projetSelectionné) );
    //ou alors
    objectifsEtTables.setModel( projetSelectionné.getObjectifs() );
     
    //dans le tableModel (façon swing) de la table
    getValue(int col, int row)
    {
      switch(col)
      {
        case 1: 
           //nom table
           return TableManager.getTablePourObjectif(objectifs[row]).getNom();
    //ou alors
           return objectifs[row].getTable().getNom(); //que j'aurais fais plus intuitivement
     
        case 2: 
           //propriété de l'objectif
           return objectifs[row].getXXX();
      }
    }
    Ce qui signifie que ma vue connait les pojo + les managers et que je fais une indirection à chaque fois que je veux accèder à un element d'une collection ?

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 69
    Points : 76
    Points
    76
    Par défaut
    Je ne te suis plus qu'à moitié. Sans doute car je ne fais jamais de Swing.

    Mais d'une manière général dans un MVC. Ta vue ne connait que tes Pojo. Ton model connait les services et les Pojo.

    Tu dois aussi savoir que par défaut Hibernate fait du "lazy loading" et que donc tu dois appeler les getters qui nécessite une requête (pour faire la jointure) supplémentaitre avant d'avoir refermer ta session hibernate.

  14. #14
    Membre du Club
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Directeur des systèmes d'information

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 64
    Points
    64
    Par défaut
    En tout cas merci pour tes réponses. Elles m'ont été d'une grande aide.
    En fait mon problème viens surtout de mon design.
    Il faut que j'arrive à clairement délimiter où les transactions commences et où elles se terminent.

    Merci encore.

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

Discussions similaires

  1. Gérer un Formulaire un peu complexe pour moi
    Par budylove dans le forum Langage
    Réponses: 3
    Dernier message: 17/05/2006, 10h01
  2. Un Alignement un peu complexe
    Par Jeskor dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 27/04/2006, 17h04
  3. Réponses: 4
    Dernier message: 02/03/2006, 20h40
  4. Requête de sélection un peu complexe
    Par new_wave dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 03/01/2006, 14h44
  5. Requete un peu complexe avec la fonction IN
    Par Taichin dans le forum Oracle
    Réponses: 27
    Dernier message: 10/11/2004, 08h59

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