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
Le 27/10/2010 10:11, Julien NICOLAS a écrit :
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. En fait, Collection<Flow> cFlow=workstation.getFlow(); copie juste la reference de la liste qui est implémenté par un proxy hibernate, donc encore sans les données chargé.
Il y a plusieurs cas (paramétrer au cas par cas les lazy à false, suivant le modele..., là difficile de répondre). Sinon, si dans ce cas vous êtes dans du code métier il est possible de forcer l'initialisation de la liste de la façon suivante : Collection<Flow> cFlow = new ArrayList<Flow>(workstation.getFlow()); (si .getFlow() est une liste, sinon new HashSet()) -- Éric <chatellier@codelutin.com> Tel: 02 40 50 29 28 http://www.codelutin.com
En fait, Collection<Flow> cFlow=workstation.getFlow();
copie juste la reference de la liste qui est implémenté par un proxy hibernate, donc encore sans les données chargé.
Sinon, si dans ce cas vous êtes dans du code métier il est possible de forcer l'initialisation de la liste de la façon suivante :
Collection<Flow> cFlow = new ArrayList<Flow>(workstation.getFlow()); (si .getFlow() est une liste, sinon new HashSet())
Merci pour cette réponse si rapide :) Malheureusement nous ne voyons pas pourquoi faire un new ArrayList avec workstation.getFlow() en paramètre actionnerait un mécanisme Hibernate pour le chargement des données.... Comme tu le dis plus haut, les données n'étant pas chargées (Lazy en cause), la fonction getFlow() renvoie une collection vide.... Pourrions-nous avoir quelques explications supplémentaires ou liens nous permettant de comprendre le fonctionnement ? J'avoue que s'il est possible de trouver une solution qui évite de paramétrer Lazy a false au cas par cas, nous voterions pour :D Merci, Julien.
-- Éric <chatellier@codelutin.com> Tel: 02 40 50 29 28 http://www.codelutin.com
_______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
Le 27/10/2010 11:57, Julien NICOLAS a écrit :
Merci pour cette réponse si rapide :)
Malheureusement nous ne voyons pas pourquoi faire un new ArrayList avec workstation.getFlow() en paramètre actionnerait un mécanisme Hibernate pour le chargement des données.... Comme tu le dis plus haut, les données n'étant pas chargées (Lazy en cause), la fonction getFlow() renvoie une collection vide.... Que ce soit avec la ArrayList ou la liste d'hibernate, si la collection est vide, c'est qu'il n'y a pas de données a charger.
Les flow sont-t-ils bien lié (topiaId) au workstation en question ? (en regardant vite fait votre code, les flows sont créé non lié et ils sont seulement lié lorsqu'ils sont démarré).
Pourrions-nous avoir quelques explications supplémentaires ou liens nous permettant de comprendre le fonctionnement ? J'ai pas trouver de doc rapidement. Le principe des LazyProxy hibernate est d'aller chercher l'information "à la demande" tant que la session est ouverte (sinon, LazyInitialisationException)
C'est proxy hibernate implémentent l'interface "List" standard donc, on ne voit pas la différence dans l'application. Après, pour la mécanique interne, je n'ai jamais été voir, mais j'imagine que les méthode de ce proxy font les requêtes SQL qui vont bien pour renvoyer les éléments demandés. -- Éric <chatellier@codelutin.com> Tel: 02 40 50 29 28 http://www.codelutin.com
Les flow sont-t-ils bien lié (topiaId) au workstation en question ?
Oui, vérifié dans la base. (en regardant vite fait votre code, les flows sont créé non lié
et ils sont seulement lié lorsqu'ils sont démarré).
Exactement, est-ce que cela pose un problème ?
Pourrions-nous avoir quelques explications supplémentaires ou liens nous permettant de comprendre le fonctionnement ? J'ai pas trouver de doc rapidement. Le principe des LazyProxy hibernate est d'aller chercher l'information "à la demande" tant que la session est ouverte (sinon, LazyInitialisationException)
C'est proxy hibernate implémentent l'interface "List" standard donc, on ne voit pas la différence dans l'application.
Après, pour la mécanique interne, je n'ai jamais été voir, mais j'imagine que les méthode de ce proxy font les requêtes SQL qui vont bien pour renvoyer les éléments demandés.
Ok donc, si j'ai bien compris ce que tu nous dis, la meilleure solution reste de configurer le chargement des données au cas par cas dans Hibernate. J'avoue que si j'avais pu écrire un truc du genre : WorkstationDAO wsDAO = EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Workstation workstation = wsDAO.findByName(pName); workstation.LoadFlowByProperties(PROPERTIE_ENDFLOW,Null); J'avoue que cela aurait été plus naturel... En tout cas merci
-- Éric <chatellier@codelutin.com> Tel: 02 40 50 29 28 http://www.codelutin.com
_______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
Le 27/10/2010 13:17, Julien NICOLAS a écrit :
(en regardant vite fait votre code, les flows sont créé non lié et ils sont seulement lié lorsqu'ils sont démarré).
Exactement, est-ce que cela pose un problème ?
Non, si le code (ci dessous) retourne la liste des Flow demarré. S'il n'y a pas de flux démarré, la liste est bien vide.
Ok donc, si j'ai bien compris ce que tu nous dis, la meilleure solution reste de configurer le chargement des données au cas par cas dans Hibernate.
J'avoue que si j'avais pu écrire un truc du genre :
WorkstationDAO wsDAO = EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Workstation workstation = wsDAO.findByName(pName); workstation.LoadFlowByProperties(PROPERTIE_ENDFLOW,Null);
Je doute du fonctionnement; si getFlow() est vide, workstation.LoadFlowByProperties... renverra un sous ensemble getFlow(), donc ici vide également. -- Éric <chatellier@codelutin.com> Tel: 02 40 50 29 28 http://www.codelutin.com
WorkstationDAO wsDAO =
EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Workstation workstation = wsDAO.findByName(pName); workstation.LoadFlowByProperties(PROPERTIE_ENDFLOW,Null);
Je doute du fonctionnement; si getFlow() est vide, workstation.LoadFlowByProperties... renverra un sous ensemble getFlow(), donc ici vide également.
Je ne sais pas si nous avons bien expliqué notre problème de chargement. Nous ne souhaitons pas monter en mémoire tous les objets contenus dans notre objet Workstation mais plutot faire du goutte à goutte en fonction des besoins... Dans un premier temps nous chargeons l'objet Workstation puis dans un deuxième temps, en fonction des cas.nous chargeons l'objet Flow ayant la propriété EndFlow à null. Le problème de la suppression de la propriété Lazy, c'est qu'a terme nous risquons d'avoir beaucoup de Flow pour une même Workstation.... 365 minimum pour ses pointages + 365 minimum par employé connecté + 1 par opération effectuée sur cette station (qui peuvent se compter par dizaine en une journée)... le tout par an. Mais nous n'avons besoin que d'un Flow à la fois par type de pointage. Voilà pourquoi nous recherchons à optimiser le chargement des données. Malheureusement, je ne vois donc pas comment il est possible de charger un flow ou l'ensemble de la collection liée à cette workstation sans changer la propriété Lazy d'Hibernate. Il n'est pas possible de charger un ou plusieurs Flow avec une condition qui serait la workstation. Il existe bien une propriété workstation dans Flow (Sa propriété workstation contient TopiaID de Workstation) mais il n'est pas possible de faire cela : FlowDAO fDAO=EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Collection<Flow> cFlow = fDAO.findByWorkstation(workstation); Voir encore plus pertinent dans notre cas : FlowDAO fDAO=EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Collection<Flow> cFlow = fDAO.findByProperties(PROPERTIE_WORKSTATION,workstation, PROPERTIE_ENDFLOW, null); Quelqu'un a -t-il une suggestion... une idée...? Une corde ? Merci encore pour l'aide apportée, Julien.
-- Éric <chatellier@codelutin.com> Tel: 02 40 50 29 28 http://www.codelutin.com
_______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
On Wed, 27 Oct 2010 14:53:18 +0200 Julien NICOLAS <nicolas.julien.cg@gmail.com> wrote:
Il n'est pas possible de charger un ou plusieurs Flow avec une condition qui serait la workstation. Il existe bien une propriété workstation dans Flow (Sa propriété workstation contient TopiaID de Workstation) mais il n'est pas possible de faire cela :
Et pourquoi ce n'est pas possible ? Car pour moi c'est la réponse: faire une requête et non pas un getFlow(). Pour moi la seul chose qui le rendrait impossible est un mauvais design du modele. Et donc modifier le modele pour pouvoir faire les requetes qu'il faut
FlowDAO fDAO=EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Collection<Flow> cFlow = fDAO.findByWorkstation(workstation);
je dirais plutot FlowDAO fDAO=EasyFlowDAOHelper.getFlowDAO(pTransaction); Collection<Flow> cFlow = fDAO.findByWorkstation(workstation);
Voir encore plus pertinent dans notre cas :
FlowDAO fDAO=EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Collection<Flow> cFlow = fDAO.findByProperties(PROPERTIE_WORKSTATION,workstation, PROPERTIE_ENDFLOW, null);
idem je dirais FlowDAO fDAO=EasyFlowDAOHelper.getFlowDAO(pTransaction); -- Benjamin POUSSIN -------------------- 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
Le 27 octobre 2010 15:22, Benjamin POUSSIN <poussin@codelutin.com> a écrit :
Collection<Flow> cFlow = fDAO.findByWorkstation(workstation);
FlowDAO fDAO=EasyFlowDAOHelper.getWorkstationDAO(pTransaction);
je dirais plutot
FlowDAO fDAO=EasyFlowDAOHelper.getFlowDAO(pTransaction); Collection<Flow> cFlow = fDAO.findByWorkstation(workstation);
Ok.... Le copier coller n'est pas l'ami du développeur... :( Donc si je comprend bien, ma première intuition était la bonne : on peut le faire (ouf !) Notre problème vient alors de notre modèle UML Merci beaucoup ! On a une piste ! Julien.
Voir encore plus pertinent dans notre cas :
FlowDAO fDAO=EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Collection<Flow> cFlow = fDAO.findByProperties(PROPERTIE_WORKSTATION,workstation, PROPERTIE_ENDFLOW, null);
idem je dirais
FlowDAO fDAO=EasyFlowDAOHelper.getFlowDAO(pTransaction);
-- Benjamin POUSSIN -------------------- 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
On 27/10/2010 15:37, Julien NICOLAS wrote:
Le 27 octobre 2010 15:22, Benjamin POUSSIN <poussin@codelutin.com <mailto:poussin@codelutin.com>> a écrit :
> Collection<Flow> cFlow = fDAO.findByWorkstation(workstation);
> FlowDAO fDAO=EasyFlowDAOHelper.getWorkstationDAO(pTransaction); je dirais plutot
FlowDAO fDAO=EasyFlowDAOHelper.getFlowDAO(pTransaction); Collection<Flow> cFlow = fDAO.findByWorkstation(workstation);
Ok.... Le copier coller n'est pas l'ami du développeur... :(
Donc si je comprend bien, ma première intuition était la bonne : on peut le faire (ouf !) Notre problème vient alors de notre modèle UML
Pour se faire il faut une bi-direction entre Flow et Workstation, ce qui me semble dangereux étant donné que Flow est lié a de nombreuses autres entités. Le mieux c'est d'avoir une requête approprié HQL (ou en utilisant TopiaQuery). un truc genre : List res = transaction.find("SELECT F FROM Flow F, Workstation W WHERE F IN elements(W.flow) AND F.end IS NULL"); Flow flow = (Flow) res.get(0); en TopiaQuery : TopiaQuery query = fDAO.createQuery("F"); query.addFrom(Workstation.class, "W"); query.addInElements("F", "W." + Workstation.PROPERTY_FLOW); query.addNull("F." + Flow.PROPERTY_END); Flow flow = fDAO.findByQuery(query); J'ai une impression de déjà vu :D
Merci beaucoup ! On a une piste !
Julien.
> Voir encore plus pertinent dans notre cas : > > FlowDAO fDAO=EasyFlowDAOHelper.getWorkstationDAO(pTransaction); > Collection<Flow> cFlow = > fDAO.findByProperties(PROPERTIE_WORKSTATION,workstation, PROPERTIE_ENDFLOW, > null);
idem je dirais
FlowDAO fDAO=EasyFlowDAOHelper.getFlowDAO(pTransaction);
-- Benjamin POUSSIN -------------------- tél: +33 (0) 2 40 50 29 28 email: poussin@codelutin.com <mailto: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 <mailto:Topia-users@list.nuiton.org> http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
_______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
On 27/10/2010 13:17, Julien NICOLAS wrote:
Les flow sont-t-ils bien lié (topiaId) au workstation en question ?
Oui, vérifié dans la base.
(en regardant vite fait votre code, les flows sont créé non lié et ils sont seulement lié lorsqu'ils sont démarré).
Exactement, est-ce que cela pose un problème ?
> Pourrions-nous avoir quelques explications supplémentaires ou liens nous > permettant de comprendre le fonctionnement ? J'ai pas trouver de doc rapidement. Le principe des LazyProxy hibernate est d'aller chercher l'information "à la demande" tant que la session est ouverte (sinon, LazyInitialisationException)
C'est proxy hibernate implémentent l'interface "List" standard donc, on ne voit pas la différence dans l'application.
Après, pour la mécanique interne, je n'ai jamais été voir, mais j'imagine que les méthode de ce proxy font les requêtes SQL qui vont bien pour renvoyer les éléments demandés.
Ok donc, si j'ai bien compris ce que tu nous dis, la meilleure solution reste de configurer le chargement des données au cas par cas dans Hibernate.
En fait non, il est dangereux de mettre des collection en lazy = false. Je rejoins Eric sur le new ArrayList(workstation.getFlow()) qui permet une copie de la liste ce qui parcours la collection getFlow. Vu qu'on est en Lazy, Hibernate est obligé d'exécuté du SQL pour récupérer les données et les charger dans la nouvelle List. Il est également possible de faire un workstation.getFlow().size(), le size oblige également le parcours et donc le chargement Hibernate. En topiaQuery j'ai rajouté la méthode addLoad qui permet de faire ca : query.addLoad(Workstation.FLOW); ou même mieux, query.addFetch(Workstation.FLOW); qui te crée une jointure avec fetch pour charger directement les données en amont et non plus à la demande. voir http://nuiton.org/embedded/topia/topia-persistence/TopiaQuery.html#chargemen... Mais toute facon ce n'est pas la bonne solution pour ton cas :D vu qu'il y a trop de Flow dans une Workstation.
J'avoue que si j'avais pu écrire un truc du genre :
WorkstationDAO wsDAO = EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Workstation workstation = wsDAO.findByName(pName); workstation.LoadFlowByProperties(PROPERTIE_ENDFLOW,Null);
J'avoue que cela aurait été plus naturel...
En tout cas merci
-- Éric <chatellier@codelutin.com <mailto:chatellier@codelutin.com>> Tel: 02 40 50 29 28 http://www.codelutin.com
_______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org <mailto:Topia-users@list.nuiton.org> http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
_______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
On Fri, 05 Nov 2010 10:29:03 +0100 Florian Desbois <florian.desbois@wiztivi.com> wrote:
On 27/10/2010 13:17, Julien NICOLAS wrote:
Les flow sont-t-ils bien lié (topiaId) au workstation en question ?
Oui, vérifié dans la base.
(en regardant vite fait votre code, les flows sont créé non lié et ils sont seulement lié lorsqu'ils sont démarré).
Exactement, est-ce que cela pose un problème ?
> Pourrions-nous avoir quelques explications supplémentaires ou liens nous > permettant de comprendre le fonctionnement ? J'ai pas trouver de doc rapidement. Le principe des LazyProxy hibernate est d'aller chercher l'information "à la demande" tant que la session est ouverte (sinon, LazyInitialisationException)
C'est proxy hibernate implémentent l'interface "List" standard donc, on ne voit pas la différence dans l'application.
Après, pour la mécanique interne, je n'ai jamais été voir, mais j'imagine que les méthode de ce proxy font les requêtes SQL qui vont bien pour renvoyer les éléments demandés.
Ok donc, si j'ai bien compris ce que tu nous dis, la meilleure solution reste de configurer le chargement des données au cas par cas dans Hibernate.
En fait non, il est dangereux de mettre des collection en lazy = false. Je rejoins Eric sur le new ArrayList(workstation.getFlow()) qui permet une copie de la liste ce qui parcours la collection getFlow. Vu qu'on est en Lazy, Hibernate est obligé d'exécuté du SQL pour récupérer les données et les charger dans la nouvelle List. Il est également possible de faire un workstation.getFlow().size(), le size oblige également le parcours et donc le chargement Hibernate.
ou plus simplement un workstation.sizeFlow() ? ca me parait quand même plus simple que tout ça (va pas utiliser une query pour faire ça quand même ???)
En topiaQuery j'ai rajouté la méthode addLoad qui permet de faire ca :
query.addLoad(Workstation.FLOW);
ou même mieux, query.addFetch(Workstation.FLOW); qui te crée une jointure avec fetch pour charger directement les données en amont et non plus à la demande.
voir http://nuiton.org/embedded/topia/topia-persistence/TopiaQuery.html#chargemen...
Mais toute facon ce n'est pas la bonne solution pour ton cas :D vu qu'il y a trop de Flow dans une Workstation.
J'avoue que si j'avais pu écrire un truc du genre :
WorkstationDAO wsDAO = EasyFlowDAOHelper.getWorkstationDAO(pTransaction); Workstation workstation = wsDAO.findByName(pName); workstation.LoadFlowByProperties(PROPERTIE_ENDFLOW,Null);
J'avoue que cela aurait été plus naturel...
En tout cas merci
-- Éric <chatellier@codelutin.com <mailto:chatellier@codelutin.com>> Tel: 02 40 50 29 28 http://www.codelutin.com
_______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org <mailto:Topia-users@list.nuiton.org> http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
_______________________________________________ Topia-users mailing list Topia-users@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-users
-- Tony Chemit -------------------- tél: +33 (0) 2 40 50 29 28 email: chemit@codelutin.com http://www.codelutin.com
participants (5)
-
Benjamin POUSSIN -
chemit -
Eric Chatellier -
Florian Desbois -
Julien NICOLAS