Salut les Topia Users, C'est encore nous et on reviens avec la même question mais on pense avoir avancé. On a simplifié nos méthodes de création, de chargement et de mise à jour des données. Nous sommes passé à une base de données postgres pour nous permettre de vérifier les données. Mais il nous reste des petits problèmes sur le chargement des données. Nous souhaitons toujours charger les flow qui constituent une workstation. Un seul, celui qui n'a pas de date de fin serait l'idéal mais comme nous l'a conseillé Benjamin, faisons simple dans un premier temps et chargeons l'ensemble des flow de la workstation. Je crains que la configuration d'Hibernate en Lazy soit la cause de notre problème. Malheureusement nous souhaitons lancer cette application sur un terminal mobile donc limité en mémoire et les flow risquent d'y être légion... On va considéré que la workstation à plus d'un flow qui lui est liée (hé hé hé, cette fois on en est sûr, on a vérifié dans la base) et que pName contient le nom de cette workstation. Nous pensions qu'un simple : WorkstationDAO wsDAO = EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Workstation workstation = wsDAO.findByName(pName); Collection<Flow> cFlow=workstation.getFlow(); Nous aurait permis de charger l'ensemble des flow.... visiblement non. Toutes les données de la workstation (notamment le TopiaID) sont ok, donc le chargement s'est bien passé. Y a-t-il une autre méthode ? utilisons nous d'une mauvaise manière ces méthodes ? Là j'avoue qu'on sèche... Merci de votre aide. Julien. Dans les épisodes précédent : Le 28 septembre 2010 12:47, Benjamin POUSSIN <poussin@codelutin.com> a
écrit :
On Tue, 28 Sep 2010 09:11:33 +0200
Julien NICOLAS <nicolas.julien.cg@gmail.com> wrote:
Bonjour les Lutins,
Sire, on en a gros....
Je préviens tout de suite, je ne vais pas répondre à la question :)
WorkstationDAO
ws_dao=EasyFlowDAOHelper.getWorkstationDAO(transaction);
context.prepareTopiaId(Workstation.class, pWorkstation);
euh, a quoi ça sert cette ligne et d'où sort cet objet context ?
FlowDAO flow_dao=EasyFlowDAOHelper.getFlowDAO(transaction); Flow newFlow = flow_dao.create( ,Flow.PROPERTY_BEGIN, pDate ,Flow.PROPERTY_RATIO,1);
ouaih, les goûts et les couleurs, mais personnellement je préfère autant les set que ce create. Car la compile ne peut pas aider à détecter les erreurs.
Donc ici on oubli et on passe à ca : FlowDAO dao=EasyFlowDAOHelper.getFlowDAO(pTransaction); Flow newFlow = new FlowImpl(); newFlow.setBeginflow(pDate); newFlow.setRatio(pRatio); dao.update(newFlow);
Et si on utilise les set, je pense qu'il faut faire un flow_dao.update(newFlow) en plus.
workstation.addFlow(newFlow); // Nous considerions que le Flow etait
lie
a la workstation ici ws_dao.update(pWorkstation); transaction.commitTransaction();
et surtout après le commit j'aurais été voir dans la base ce qui a été enregistré réellement.
Nous nous assurions que les donnees etaient bien presentes par le chargement de la workstation par son nom puis du Flow par son TopiaID.
Ok, mais je préfère tout de même regarder dans la base pour bien comprendre comment est fait le stockage. Y'a jamais rien de magique en informatique et si on le croit c'est une grosse erreur :)
Nous avons donc changé de base pour une base postgres que nous connaissons mieux et que nous pouvons inspecter régulièrement.
Seulement lorsque nous avons voulu charger une workstation et tout les flows qui lui sont lies il n’y avait aucun flow associes a la workstation. Voici la requete TopiaQuery qui nous permet de recuperer la workstation et ses Flows :
WorkstationDAO wsDAO = EasyFlowDAOHelper.getWorkstationDAO(transaction); TopiaQuery wsQuery = wsDAO.createQuery("W"); wsQuery.addEquals(Workstation.PROPERTY_NAME,wsName); wsQuery.addLoad(Workstation.PROPERTY_FLOW); Workstation workstation = wsDAO.findByQuery(wsQuery);
euh, pourquoi se compliquer la vie et ne pas faire simplement
WorkstationDAO wsDAO = EasyFlowDAOHelper.getWorkstationDAO(transaction); Workstation workstation = wsDAO.findByName(wsName); List<Flow> flows = workstation.getFlow();
Oui, ca parait plus simple. Le hic c'est que là, je n'arrive pas à charger la collection... Nous sommes configuré en Lazy pour ne charger que le niveau workstation. J'ai peur qu'en remontant l'ensemble des objets liés à la workstation nous saturions la mémoire (on doit mettre exécuter cette application dans un terminal mobile).
En général toujours faire simple avant de rechercher la performance. Car souvent les goulots d'étranglements ne sont pas là où on les attendait. Donc ça sert à rien d'optimiser par du code compliqué quelque chose qui n'en à pas besoin.
Nous avons alors remis en cause le diagramme precedent et nous avons modifie la liaison Workstation / Flow comme sur le diagramme suivant :
http://www.nomaka.fr/img/UML_Apres.png
ce qui nous donne une nouvelle fonction de creation du flow comme suit :
WorkstationDAO ws_dao=EasyFlowDAOHelper.getWorkstationDAO(transaction); context.prepareTopiaId(Workstation.class, pWorkstation); FlowDAO flow_dao=EasyFlowDAOHelper.getFlowDAO(transaction); Flow newFlow = flow_dao.create( Flow.PROPERTY_WORKSTATION,pWorkstation // ici on se dit que cette fois, nous avons bien la relation.... ,Flow.PROPERTY_BEGIN, pDate ,Flow.PROPERTY_RATIO,1); pWorkstation.addFlow(newFlow);
mauvais design, double set dans les deux sens, super dur à maintenir la cohérence, et donc potentiellement de nombreux bug incompréhensible :(
Message reçu. Après vérification dans la base, nous avons tous ce dont nous avions besoin avec un lien dans un seul sens.
ws_dao.update(pWorkstation); transaction.commitTransaction();
Nous utilisons la meme methode de chargement qui ne nous renvoie
toujours
pas ce qu’il nous faut...
La requete que nous avons reelement besoin est plus restrictive et utilise un fetch mais ne recupere pas non plus le flow (logique en fait) : WorkstationDAO wsDAO = EasyFlowDAOHelper.getWorkstationDAO(transaction); TopiaQuery wsQuery = wsDAO.createQuery("W"); wsQuery.addEquals(Workstation.PROPERTY_NAME,wsName); wsQuery.addFrom(Flow.class,"F"); wsQuery.addLeftJoin("W."+Workstation.PROPERTY_FLOW, null, true); wsQuery.addWhere("F."+Flow.PROPERTY_END+" IS NULL"); Workstation workstation = wsDAO.findByQuery(wsQuery);
Je ne cherche même pas à la comprendre celle là ;)
Ecrit en topia query ca fait mal aux yeux mais en SQL C'est 2 requêtes. Une pour charger la workstation et l'autre pour charger le flow qui n'a pas de date de fin...
Nous pensons que nous avons un probleme avec nos relations dans notre diagramme UML mais nous ne voyons pas ce qui ne vas pas... Si c’est un probleme de code, nous ne voyons pas non plus...
Quelqu’un aurait une idee ?
non :)
:D
--
Benjamin -------------------- tél: +33 (0) 2 40 50 29 28 email: poussin@codelutin.com () campagne du ruban ascii http://www.codelutin.com /\ pour les mails en ascii _______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users