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

Java Discussion :

Gros pb generic reflection, besoin d'idées


Sujet :

Java

  1. #1
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 41
    Par défaut Gros pb generic reflection, besoin d'idées
    Bonjour,

    on m'a demandé de parser un fichier et d'enregistrer les infos en base, le fichier correspond a une 100 aine de tables.

    On ma indiqué vouloir du générique, pour ne pas faire une méthode par type de données a enregistré (table) et afin qu'en cas d'ajout de modification ou autre du fichier à parser, les changements à faire soient minimes et ne quasi pas toucher au code. J'ai indiqué que c’était un peu usine à gaz et surtout que niveau perf c’était moyen.

    J'ai bossé la dessus, j'ai fais mes classes, j'ai une enum qui contient : nomDeTable("nomVariable1", "tailleDuChampDansLeFichier", "nomVariable2", "tailleDuChampDansLeFichier", etc...);

    Ca fonctionne pour la lecture et l'enregistrement, en fait je recupère la classe, je fais un entity = c.newInstance() ou c'est est la class. Je recupère dans l'enum de nom de la variable, je fais un set de la variable avec en paramétre un substring en utilisant la "taille du champ dans le fichier" (nombre de caractère à recuperer dans la ligne) et je fais ca avec tous les setters. Entre temps je donne un type à la variable pour que le setter ne m'envoi pas chi*r.

    Ca fonctionne, mais mon (mes) problèmes :

    - C'est bien d’enregistrer, mais si l'entité existe déjà la base, il faut la mettre à jour. Le problème, c'est la pk ! Lorsqu'elle correspond à une seule variable, pas de soucis, mais quand il s'agit d'une pk qui est un numéro attribué auto, ou qu'il s'agit d'un ID composé, je n'arrive pas à récupérer les ID. J'ai testé un truc qui fonctionne bien, mais niveau perf c'est catastrophique, c'est récupérer la totalité de la table en question et d'utiliser un equals que j'ai redéfini. Mais vous imaginez bien la cata lorsqu'il faut récupérer une table qui contient 2000 enregistrements. J'ai voulu utiliser l'embaddable et embedded id mais le problème, c'est que comme je set les variables une a une, je n'arrive pas a créer la pk puisque je ne passe pas par le constructeur. J'ai voulu tester (rapidement) la création d'une entité avec le constructeur non vide mais le problème, c'est qu'il n'y a jamais le même nombre de paramètres suivant l'entité, donc comment passer les données "découpées" dans le constructeur ?

    - On m'a dit, que vu la complexité et que les perf sont moins bonnes, que si je voulais je pouvais ne pas partir sur le generique mais en gardant toujours une enum ou autre qui defini comment decouper chaque ligne. Le problème, il me reste plus que 3 semaines, et j'aurais aimé avoir quelque chose à présenter au jury, sinon c'est la m**de.

    Donc vu que je n'ai personne pour m'aider la bas, que mon "tuteur" n'est jamais présent, qu'il n'est venu me voir qu'une seule fois (hier) depuis le début du stage, je me permet de vous solliciter afin de savoir si vous auriez une "solution" pour terminer en générique ou une solution assez rapide à mettre en place (sachant que les classes sont faites, l'enum aussi, et qu'il n'y a "que" le code métier a terminer) qui n'utiliserait pas la généricité ?

    Je vous remercie d'avance, ça me ferais ch*er de me planter alors que la formation se passe super bien, que je n'ai que des compliments, que je me donne a fond, mais que j'ai choisi en toute connaissance de cause, le stage ayant un niveau de difficulté le plus élevé pour en apprendre le plus possible (ce qui n'est pas le cas vu que je me retrouve seule, sans aide).

    J’élèverai un autel à votre gloire, prierai et sacrifierai des animaux en l'honneur au forum, si vous arrivez à m'extirper de se merd*er.

  2. #2
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Dans la mesure où tu dois écrire des données dans une base de données, je m'étonne de ne pas voir apparaître JDBC dans ton message, c'est fait pour, pas très compliqué, bref, tout ce qu'il te faut.
    Je te conseille vivement de jeter un œil sur cette techno, personnellement, je l'utilise dans une API faite... pour intégrer des données venant de fichiers CSV dans une base de données... pour te dire si c'est adapté !
    Pour ce qui est des contrôle, JDBC a des méthodes qui permettent d'extraire la structure des tables, longueur des champs, clé primaire, index etc...
    Tu peux regarder ce tutoriel pour te faire une idée.

    Pour le "super générique", tu pourrais partir sur un Statement réutilisé pour toutes les opérations mais bon, je te le déconseille, le risque d'injection est beaucoup trop élevé.
    Pour ma part, j'utilise des PreparedStatement (la seule chose à définir spécifiquement pour la table cible) et ensuite, y a plus qu'à...
    Pour savoir si ta clé existe déjà, tu peux par contre faire une méthode générique via un Statement. Il va de soi que la requête sur un ID auto incrément ne fonctionne que si tu as cet ID dans ton fichier source, sinon, il faut avoir des clés logiques pour savoir si ton enregistrement existe ou non.

    Bref, tu as du boulot
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 41
    Par défaut
    Merci pour ta réponse.

    Je n'avais jamais utilisé JDBC excepté pour la connexion à la DB. Je savais pas qu'il y avait plus que ca.

    Par contre le framework de l'entreprise ne permet pas d'utiliser ce que l'on veut, ce qui m'est imposé c'est les EJB QL et les string builders pour créer les requêtes. J'avoue ne pas savoir si JDBC peut être utilisée dans le framework.

    Juste une question, plus niveau conception que dev, comment concevoir cela ? Des @NamedQueries dans chaque classe avec les requêtes pour Update, Insert. Puis dans le code métier un minimum de générique qui créée un classe selon la ligne du fichier à parser. Découpage de la ligne, et appel de la namedQuery ? Ou je suis dans le faux depuis le début ?

    Concernant les pk, j'ai essayé de définir une interface avec une méthode Recuperation_Id, mais pour les clés composées, j'ai tout passé en Embaddable et EmbeddedId mais je sais pas si c'est le framework ultra restrictif ou autre, mais ça marchait pas. Alors qu'il y a rien de plus simple qu'une clé composée que tu peux porter dans une classe, je l'ai utilisé je sais pas combien de fois depuis le début de la formation sur tous les projets auxquels j'ai participé. Enfin bref, j'étais pas fan de généricité, ça s'arrange pas.

    Tu pense qu'il y a moyen de refaire le code de parsing en 3 semaines ? Les classes et l'enum définissant les "curseurs" de position sont déjà fait !

    Merci encore.

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Si tu dois rester dans le monde JPA, la persistence est déjà entièrement générique puisque tu fais un persist(...) ou merge(...) via l'EntityManager, donc, de ce côté, c'est simple.
    Le problème est plutôt l'alimentation de la classe entity de manière générique.
    Ceci dit, via l'introspection, c'est tout à fait possible, si tu connais le nom de la colonne cible pour une données source de ton fichier d'entrée, c'est même relativement simple.
    Voici un exemple
    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
    30
    31
    public class MonEntity
    {
        private Integer uid;
        private String libelle;
     
        public Integer getUid()
        {
            return uid;
        }
     
        public void setUid(Integer uid)
        {
            this.uid = uid;
        }
     
        public String getLibelle()
        {
            return libelle;
        }
     
        public void setLibelle(String libelle)
        {
            this.libelle = libelle;
        }
     
        @Override
        public String toString()
        {
            return "MonEntity [uid=" + uid + ", libelle=" + libelle + "]";
        }
    }
    Le code utilisant l'introspection
    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
            try
            {
                Field fieldUid = MonEntity.class.getDeclaredField("uid");
                fieldUid.setAccessible(true);
                Field fieldLibelle = MonEntity.class.getDeclaredField("libelle");
                fieldLibelle.setAccessible(true);
     
                MonEntity entity = new MonEntity();
     
                fieldUid.set(entity, 1);
                fieldLibelle.set(entity, "libelle 1");
     
                System.out.println("Valeur de l'entity : " + entity.toString());
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 41
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Le code utilisant l'introspection
    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
            try
            {
                Field fieldUid = MonEntity.class.getDeclaredField("uid");
                fieldUid.setAccessible(true);
                Field fieldLibelle = MonEntity.class.getDeclaredField("libelle");
                fieldLibelle.setAccessible(true);
     
                MonEntity entity = new MonEntity();
     
                fieldUid.set(entity, 1);
                fieldLibelle.set(entity, "libelle 1");
     
                System.out.println("Valeur de l'entity : " + entity.toString());
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    C'est exactement ce que j'ai fais ! Aucun pb pour persist. Mon problème en fait, c'est de recuperer l'id, pour qu'apres parsing du fichier, verifier si l'entité existe déjà, afin de savoir s'il faut persist ou juste mettre à jour. Ca ne pose pas de problème, lorsque l'id correspond à une seule variable, c'est lorsque l'id est composé ou que l'id est generé par la DB que je suis bloqué.

    En fait, mon problème, je pense que c'est la création de la clé composée. Puisque j'appelle les setters de chaque variables, je ne passe pas par le constructeur, l'id ne se genère pas. C'est pour ca que je voulais faire des embeddedid et embeddable, mais pour une raison que j'ignore, je n'arrive pas à faire remonter de la DB l'entité qui correspond. Et je ne sais même plus si j'arrive a creer la pk (j'ai fais tellement d'essais, j'en suis perdu).

  6. #6
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Si je comprends bien, tu instancies un objet représentant la clé primaire et j'imagine que tu fais un entityManager.find(...) pour tester l'existance.
    Je ne vois pas trop l'intérêt de faire comme ça, tu n'as qu'à utiliser un Query, là, tu n'as qu'à construire ta requête dans le genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    Query query = entityManager.createQuery("select a from MonEntite a where colonneCle1=:cle1 and colonneCle2=:cle2");
    Object entity = query.getSingleResult();
    Cette partie est presque générique, à part la clause where mais comme c'est une construction de chaîne ça reste assez "générique", ensuite, si tu as une entité en retour, tu fais un merge, sinon, un persist après avoir créé une instance de la classe, le code qui mettra à jour les attributs lui est générique via l'introspection.
    Pour identifier l'objet représentant la clé primaire, tu peux utiliser l'analyse des annotations (@ID en particulier).
    C'est un peu chiant mais bon, tu peux faire un truc comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for (Method method : Entite.class.getMethods())
    {
        if (method.getAnnotation(Id.class) != null)
        {
            System.out.println(method.getName() + " est la méthode ID");
            System.out.println("Le type de l'ID est : " + method.getReturnType());
        }
    }
    Ensuite, je ne comprends pas trop ton problème avec les clés auto-générées, comme leur nom l'indique, tu n'as pas à t'en occuper, la base s'en chargera toute seule.... j'ai raté un truc ?

    Enfin bref, ça aurait été beaucoup plus simple en passant par JDBC, mais c'est mon avis
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 41
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Si je comprends bien, tu instancies un objet représentant la clé primaire et j'imagine que tu fais un entityManager.find(...) pour tester l'existance.
    En fait, j'ai peut etre pas reflechi assez, zut j'ai pas le code pour montrer. En fait je recupère la class et je fais un c.newInstance().
    Ensuite je recupère la liste des setters et j'attribue une valeur avec method.invoke().
    Du coup je crée l'entité complète et ensuite je verifie si elle est présente en base. En lisant ta réponse je me dis, mais oui, pk comparé l'entité complète alors que la pk suffit ?

    Citation Envoyé par OButterlin Voir le message
    Je ne vois pas trop l'intérêt de faire comme ça, tu n'as qu'à utiliser un Query, là, tu n'as qu'à construire ta requête dans le genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    Query query = entityManager.createQuery("select a from MonEntite a where colonneCle1=:cle1 and colonneCle2=:cle2");
    Object entity = query.getSingleResult();

    La clé composée, en general quand j'utilise cela, je met ca dans le constructeur avec pk = new pk(paramètres); mais la je passe pas par le constructeur d'ou la difficulté à creer la clé composée. Mais je suis en train de me dire, que si j'utilise embaddable et embedded id je peu utiliser un setter et passer en paramètre les valeurs... à tester.

    Je voulais justement utiliser un Query, mais le problème, sans doute idiot mais je ne suis pas experimenté, c'est que chaque entité à un nombre différents de clés qui composent la clé primaire, donc y a peut etre un moyen de faire un Stringbuilder avec une boucle pour justement passer plusieurs clés d'un nombre indeterminé de valeur composant la pk ? ? ?


    Citation Envoyé par OButterlin Voir le message
    Cette partie est presque générique, à part la clause where mais comme c'est une construction de chaîne ça reste assez "générique", ensuite, si tu as une entité en retour, tu fais un merge, sinon, un persist après avoir créé une instance de la classe, le code qui mettra à jour les attributs lui est générique via l'introspection.
    Pour identifier l'objet représentant la clé primaire, tu peux utiliser l'analyse des annotations (@ID en particulier).
    C'est un peu chiant mais bon, tu peux faire un truc comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for (Method method : Entite.class.getMethods())
    {
        if (method.getAnnotation(Id.class) != null)
        {
            System.out.println(method.getName() + " est la méthode ID");
            System.out.println("Le type de l'ID est : " + method.getReturnType());
        }
    }
    Ensuite, je ne comprends pas trop ton problème avec les clés auto-générées, comme leur nom l'indique, tu n'as pas à t'en occuper, la base s'en chargera toute seule.... j'ai raté un truc ?

    Enfin bref, ça aurait été beaucoup plus simple en passant par JDBC, mais c'est mon avis [/QUOTE]

    J'avoue avec JDBC ca aurais été plus simple, mais on m'impose ce choix mais si je m'en sort pas, je veux pas me retrouver le bec dans l'eau devant le jury sans rien à presenter du coup j'utiliserai jdbc.

    Pour l'auto-générée, en fait, comment je compare l'entité que je crée en parsant, et celle en base ? Puisque toutes les valeurs de l'entité en base peuvent potentiellement changer, comment je peu dire, tiens, l'objet que j'obtiens en parsant, il faut que je verifie s'il existe en base ? (puisque je ne connais pas la pk, elle est auto-générée, et je peu pas verifié, meme en redifinissant equals si l'entité est identique vu que justement je dois la mettre à jour).

    Voila, j'espère que j'arrive à me faire comprendre, mais sinon je mettrai des bouts de code demain quand j'aurai acces à mon code. En attendant merci pour tes réponses.

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    L'avantage du query c'est que tu te fiches de la structure de l'entité, tu génères une requête SQL avec un nombre variable d'éléments (qui correspondent à ta clé composite) et ensuite, SQL se débrouille.
    A l'arrivée, soit tu as une entité et tu la modifies (sans prendre en compte l'ID) soit tu dois créer une nouvelle instance de ta classe entité (avec newInstance() par exemple) et alimenter tous les champs avec la problématique de l'objet représentant la PK.

    Pour l'histoire de l'ID auto-généré, pour savoir si l'enregistrement existe déjà (si tu n'as pas l'ID dans ton fichier d'entrée bien sûr) il te faut une clé logique (ou métier) pour faire la recherche, sinon, bien sûr, tu ne pourras pas faire de test et là, à tes encadrant de te dire par quel miracle tu vas pouvoir déterminer l'existence
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 41
    Par défaut
    Ok je te remercie, j'espère pouvoir m'en sortir avec ces infos !

    Sinon, dernière question idiote, comment tu passes un nombre variable d'element dans une requete ? Quand tu utilises le stringbuilder tu fais une boucle pour concatener un string que tu passes en paramètres ?

  10. #10
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Ce que je ferais personnellement c'est passer une Map<String, Object> avec le nom de la colonne cible en clé et la valeur de la clé + le nom de l'entité cible, du coup, tu peux faire une méthode générique qui va construire et exécuter la requête et renvoyer un Object ou null.
    La méthode fait une itération sur les clés de la Map pour ajouter les critères au StringBuilder, elle construit l'objet Query, refait une itération sur les clés de la Map pour affecter les valeurs aux paramètres de la requête et hop
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 41
    Par défaut
    lol je crois qu'on a eu la même idée, j ai testé en arrivant au boulot (ca m'est venu dans la nuit) et ca fonctionne (a un detail) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		final StringBuilder req = new StringBuilder();
    		req.append("SELECT obj ");
    		req.append("FROM " + c.getName() + " obj ");
    		req.append("WHERE ");
    		req.append(String.join(" AND ", mapId.entrySet().stream().map(entry -> entry.getKey() + " = :" + entry.getKey()).collect(Collectors.toList())));
    		final Query q = getInnerEntityManager().createQuery(req.toString());
    		mapId.entrySet().stream().forEach(entry -> q.setParameter(entry.getKey(), entry.getValue()));
    Je dis presque, car en fait, lorsque je passe une date dans l'un des deux j'ai une erreur du type :

    ORA-00932: types de données incohérents ; attendu : DATE ; obtenu : BINARY

    après verification, mon entity defini bien une date, ou plutot nomEntrepriseCalendar qui herite de GregorianCalendar.
    Dans le debugger, j'ai bien dans la map, une value de type nomEntrepriseCalendar.
    Après dans la DB Oracle, c'est un format date (dd/MM/yy) et le Calendar dans la map c'est yyyyMMdd donc c'est peut etre ca, mais c'est bizarre car quand c'est pas un id il m'enregistre bien le Calendar au bon format. J'ai pas encore testé faut que je le fasse.

    En tout cas je te remercie beaucoup pour tes reponses et de m'avoir aiguillé.

  12. #12
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Dans ta Map, tu as un type java.util.Date ou autre chose ?
    Là, l'erreur est un peut louche : BINARY reçu ???
    Dans tous les cas, ce n'est pas bien grave, au pire, tu peux toujours faire des cast dans la méthode d'affectation ou créer le type qui va bien, comme c'est une méthode générique, c'est centralisé.
    Ceci dit, je n'utilise pas Oracle et avec DB2, PostgreSQL ou MySQL, ça fonctionne correctement l'affectation par query.setParameter(...), c'est vrai qu'il faut se soucier en amont de placer la bonne valeur dans le bon type mais c'est un minimum.
    Pour ce qui est du format d'affichage, ça n'a pas vraiment de conséquence, là, tu affectes (ou tu es sensé affecter) un objet Date au paramètre.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 41
    Par défaut
    J'ai trouvé, j'ai une méthode qui cast mon string dans le format desiré (String, Integer, Big Decimal, etc.) j'avais mis nomEntrepriseCalendar et j'ai changé par Calendar, et ca fonctionne, je pense qu'il faut utiliser les classes enveloppes et pas les types primitifs pour que ca fonctionne apparemment.

    En tout cas, merci bcp pour ton aide. Maintenant je vais m'attarder sur les autres soucis

    Des fois j'ai l'impression de creer un ORM lol

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

Discussions similaires

  1. popup à la mano, besoin d'idées
    Par Alec6 dans le forum JSF
    Réponses: 2
    Dernier message: 15/01/2007, 15h00
  2. Besoin d'idées pour macro word
    Par christel91 dans le forum VBA Word
    Réponses: 9
    Dernier message: 29/11/2006, 10h47
  3. Besoin da'ide pour le Déploiment d'une Application VB6 sur un Serveur d'application
    Par blowlagoon dans le forum Installation, Déploiement et Sécurité
    Réponses: 4
    Dernier message: 03/08/2006, 00h24

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