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

NHibernate Discussion :

DAL avec NHibernate en mode déconnecté


Sujet :

NHibernate

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2006
    Messages : 23
    Points : 24
    Points
    24
    Par défaut DAL avec NHibernate en mode déconnecté
    Bonjour,
    Je développe une application Winform et j'utilise NHibernate pour l'accès aux données.
    J'essaye architecturer mon application selon les préconisations de nos amis Sami Jabber ou Thomas Lebrun (CF Introduction au développement en couches) (Merci à eux au passage)

    de manière à avoir :
    • une couche présentation des données => Winform
    • une couche de service qui propose de récupérer, mettre à jour des objets ou liste d'objets métiers (sans notion de session :erreur ?)
    • une couche d'accès au données qui encapsule NHibernate.


    Le problème c'est que lorsque dans ma couche de présentation j'utilise un objet métier par exemple Client , j'ai parfois (pas nécessairement) besoin d'accéder aux attributs d'objets référencés par cet objet Client par exemple Client.Commandes ou Client.Adresse.
    Mais comme je suis hors transaction, NHibernate me renvoi une exception par exemple : "failed to lazily initialize a collection, no session or session was closed"

    Dans ma méthode ClientDao.ClientById(int) je ne peux pas charger toutes les dépendences systématiquement sinon je risque de remonter une bonne partie de la base pour la moindre petite opération !

    Est-ce que je dois donc avoir plusieurs méthodes en fonction des usages ?
    par exemple :
    ClientDao.GetClientById(int oid) // Charge l'objet avec seulement les attributs simples
    ClientDao.GetClientById(int oid, bool getAdresse) // Charge l'objet et l'objet référencé Adresse
    ClientDao.GetClientById(int oid, bool getAdresse, bool getCommandes) // charge l'objet complet Client et ses dépendances

    Problème avec cette approche :
    Dans une form j'utilise ClientDao.GetClientById(int oid, bool getAdresse) mais je souhaite obtenir des infos sur un objet référencé par Client.Adresse qui n'est pas chargé (Adresse référence un objet Etablissement).
    Dois-je créer une nouvelle méthode sur ClientDao pour cet usage ?

    A part créer une session (Nhibernate.ISession directement (entorse à la séparation) ou un wrapper de Session) dans ma couche de présentation qui me permettrai de charger des objets référencés à la demande, je ne vois pas comment faire sinon ça risque d'être un "joyeux bordel" dans mon DAO ; les programmeurs de la couche présentation ne seront pas vraiment quelle méthode prendre et/ou voudront accéder quelque fois à des objets non chargés (et obtiendront inévitablement une exception)...

    Tout ceci est dû, je pense au fait que je travaille en mode "déconnecté" : ma couche de service charge des objets, les détache (ferme la session), travaille avec et éventuellement les ré-attache (les réinjecte dans une autre session par ex pour faire un SaveOrUpdate), dans ma couche de service je n'ai pas (encore) de notion de session.

    N'hésitez pas à me répondre, si vous avez des conseils, des urls de tutoriaux et pour me dire comment vous faites de votre côté.

    Fx

    nb: Faisons abstraction ici du nommage "franglais" c'est pour essayer de mieux me faire comprendre

  2. #2
    mow
    mow est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 210
    Points : 166
    Points
    166
    Par défaut
    Salut,

    Je crois que tu as la réponse ; il te suffit d'enrichir ta classe ClientDAO.cs
    je fais de même à la différence près que il y aurait une fonction pour récupérer les différentes commandes/adresses.
    En fait, cela n'est nécessaire que pour les collections je dirais...

    ...
    ...

    Mow

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 15
    Points : 10
    Points
    10
    Par défaut NHibernate en winforms et lazy propriétés...
    Salut,
    J'ai écrit deux articles (en anglais) sur les sujet de l'utilisation de NH dans une application winforms.

    En gros, il s'agit d'un sujet assez délicat- si tu laisse la session ouvert, tu risque d'avoir de sessions énormes et probablement polluées... Donc, il te faudra de faire des aller-retour à la base chaque fois, ce qui veux dire que ce sera plus sensible de charger avant en une seule fois le plus d'info possible (ce qu'il te faut vraiment - pas plus ni moins...) et puis chaque fois que t'en a besoin, ouvrir une session pour chercher les refs demandés...
    Pour cela je te conseille d'utiliser spring.net ou n'importe qu'elle autre utilitaire AOP pour remplacer les using de Transaction et session.Open()/Flush()/Close() par des 'attributes' ([Transaction]).

    Il faut aussi se souvenir de jamais charger des objet et oublier fermer la session!! (-avec spring.net ça veut dire toujours utiliser le [Transaction] attribute, même pour les transaction read only...)

    et oui, désolé pour mon français
    j'espère que ça t'aidait

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2006
    Messages : 23
    Points : 24
    Points
    24
    Par défaut
    Salut CSharper,
    Merci pour ta réponse,
    Après plusieurs essais, je suis revenu a une architecture moins propre mais beaucoup plus simple, une DAL en mode connectée ! Et ce malgrès les risques ou problème que cela peut engendrer.
    Car en mode déconnecté, il faut toujours réfléchir à l'usage des objets dans la form: quels objets vont être utilisés quels attributs doivent être chargés, qu'est-ce qu'il faut charger au préalable, etc, etc.

    Je fais ce choix, car dans mon application, il y a peu de chance que 2 personnes modifient la même donnée au même moment.

    Grosso modo, voici la solution pour laquelle j'ai obté pour le moment :
    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
     
                ....
                using (ISession session = persistenceManager.OpenSession()) {
                    using(ITransaction tx = session.BeginTransaction()) {
                        Patient patient = PatientDao<Patient>.Instance.GetPatient(session, patientId);
                        if (patient !=null) {
                            PatientForm form = new PatientForm(patient);
                            if (form.ShowDialog() == DialogResult.OK) {
                                session.Update(patient);
                                tx.Commit();
                            }
                        } else {
                            ....
                        }
                    }
                }
    Sinon, pour ce qui est de l'usage de Spring, je trouve ce framework beaucoup trop compliqué, complexe à mettre en oeuvre, en plus c'est très intrusif au niveau du source (peut-être je changerai d'avis dans qq mois ou années). Je suis sûr qu'il peut apporter des tas de bonnes choses, mais je ne peux pas me permettre de mettre trop de technos/architectures avancés dans mon application si je souhaite qu'un développeur "lambda"(niveau moyen) prennent le relais à l'avenir.

    Bravo, pour tes articles ils ont l'air très interressants, je vais étudier ça ce week-end.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par kfx_2000 Voir le message
    Salut CSharper,
    Merci pour ta réponse,
    Après plusieurs essais, je suis revenu a une architecture moins propre mais beaucoup plus simple, une DAL en mode connectée ! Et ce malgrès les risques ou problème que cela peut engendrer.
    Car en mode déconnecté, il faut toujours réfléchir à l'usage des objets dans la form: quels objets vont être utilisés quels attributs doivent être chargés, qu'est-ce qu'il faut charger au préalable, etc, etc.

    Je fais ce choix, car dans mon application, il y a peu de chance que 2 personnes modifient la même donnée au même moment.
    Salut kfx,
    tout d'abord, pour le mode connectée- évidemment, s'il s'agit d'une petite application, ça peut marcher mais, et c'est un grand mais, je te rappelle que plus l'utilisateur laisse une fenêtre ouverte, plus la session deviendra grande, lourde et chère au niveau de performance de l'application. En plus, si vous ouvrez une boite de dialogue qui utilise une nouvelle session, la session de la fenêtre mère deviendra "stale" avec tous les infos qui sont dedans... en tout cas, bonne chance

    Pour le code de using le session et transaction, je te conseille d'utiliser un framework AOP pour utiliser des attributes pour gérer le duplication de code, mais bon, ce juste plus propre rien d'autre.

    Citation Envoyé par kfx_2000 Voir le message
    Sinon, pour ce qui est de l'usage de Spring, je trouve ce framework beaucoup trop compliqué, complexe à mettre en oeuvre, en plus c'est très intrusif au niveau du source (peut-être je changerai d'avis dans qq mois ou années). Je suis sûr qu'il peut apporter des tas de bonnes choses, mais je ne peux pas me permettre de mettre trop de technos/architectures avancés dans mon application si je souhaite qu'un développeur "lambda"(niveau moyen) prennent le relais à l'avenir.
    Alors, ça je comprends à 100%. Ce n'est pas évident et pas pour tous le monde, surtout si tu essaye d'éviter trop de technos/architectures avancés. Bonne chance avec ton application! Si vous avez des questions sur NH, n'hésitez pas- ici ou dans le google groupe NH-FR.

Discussions similaires

  1. Réponses: 7
    Dernier message: 08/12/2010, 11h33
  2. Réponses: 2
    Dernier message: 17/03/2009, 11h46
  3. [Débutant] Mode déconnecté avec ADO.NET
    Par bilred dans le forum Débuter
    Réponses: 2
    Dernier message: 25/11/2008, 16h32
  4. Réponses: 4
    Dernier message: 11/05/2006, 16h57
  5. [Vb.net][Ado.net] mode déconnecté avec sql
    Par hoummass dans le forum Accès aux données
    Réponses: 6
    Dernier message: 27/11/2005, 15h10

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