Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 2 sur 2
  1. #1
    Invité de passage
    Inscrit en
    septembre 2011
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : septembre 2011
    Messages : 3
    Points : 1
    Points
    1

    Par défaut Migration NHbernate 1.2 vers 3.2

    Bonjour,

    Je suis en train d'effectuer une migration d'un projet sous NHibernate 1.2 vers la version 3.2 et j'ai un problème au niveau du chargement d'une collection.

    En gros j'ai une classe "Carton" et une classe "Boite", un carton peut contenir plusieur boites. Dans ma classe Carton j'ai une propriété "Inventaire" en virtual qui permet d'accéder à ces cartons.

    Au lancement de mon appli tout va bien, ma requête va bien récupérer mon carton, mais la propriété reste vide. Il me semble que lazy loading par défaut est activé, j'ai essayé de mettre ce lazy à false un peu partout mais rien n'y fait, je vois bien que le chargement met plus de temps mais rien n'est récupéré.

    J'ai bien évidemment fait le mapping puisque cela fonctionnnait très bien en version 1.2.

    Voici mon app.config :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
        <session-factory>
                <property name="dialect">NHibernate.Dialect.FirebirdDialect</property>
          <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
          <property name="connection.driver_class">NHibernate.Driver.FirebirdClientDriver</property>
          <property name="connection.connection_string">server=dev;User=toto;Password=tata;Database=titi;Charset=ISO8859_1;</property>
          <property name="show_sql">true</property>
          <property name="query.substitutions">true 1, false 0</property>
          <mapping assembly="CACAO_Framework"/>
        </session-factory>
      </hibernate-configuration>
    La requête qui récupère mon carton:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
     
    public static Carton GetCartonById(long id)
            {
                IQuery srv = GetCurrentSession().CreateQuery("from Carton c where c.Id  = :id");
                srv.SetParameter("id", id);
                Carton result = srv.UniqueResult<Carton>();
                return result;
            }
    Est-ce une histoire de lazy loading ?
    Ou comment dans ma requête puis je faire un "Load" comme en Linq ?
    Des idées ?

    Merci d'avance.

  2. #2
    Membre habitué
    Homme Profil pro Alexandre Trigueros
    Architecte C#
    Inscrit en
    février 2003
    Messages
    77
    Détails du profil
    Informations personnelles :
    Nom : Homme Alexandre Trigueros
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte C#

    Informations forums :
    Inscription : février 2003
    Messages : 77
    Points : 140
    Points
    140

    Par défaut

    Bonjour,
    par un "Load", tu veux dire une commande comme :
    Code :
    1
    2
    var session = GetCurrentSession();
    return session.Load<Carton>(id);
    Les méthodes Load & Get sont déjà existantes dans la session.

    Attention : Get te renverra null si il ne trouve pas l'id et Load te renverra un proxy qui lancera une exception si l'objet n'existe pas quand tu voudra y accéder.

    Pour forcer le fetching de la collection, tu peux la désactiver dans le mapping (lazy="false") forcer à faire un jointure ("fetch=join")

    d'autres méthodes existent également pour le hql, le requetage par criteria & QueryOver

    Pour le hql :
    Code :
    from Carton c where c.Id  = :id left join fetch c.Inventaire
    Pour l'api criteria - setFetchMode
    Code :
    1
    2
    3
    4
    5
    6
    var result = GetCurrentSession()
                    .CreateCriteria<Carton>()
                    .SetFetchMode("Inventaire", FetchMode.Eager)
                    .Add(Restrictions.Where<PDCInfo>(carton => carton.Id == id))
                    .SetResultTransformer(Transformers.DistinctRootEntity)
                    .UniqueResult<Carton>();
    et enfin pour la queryOver :
    Code :
    1
    2
    3
    4
    5
    6
    var result = GetCurrentSession()
                    .QueryOver<Carton>()
                    .Where(carton => carton.Id == id)
                    .Fetch(carton => carton.Inventaire).Eager
                    .TransformUsing(Transformers.DistinctRootEntity)
                    .SingleOrDefault();
    Si tu as systématiquement besoin de l'information inventaire, autant la mapper en eager / join dans le mapping.
    Sinon, faire une requete, la plus simple possible et spécifier le résultat.

    Attention, avec les requêtes à jointure, tu peux te retrouver avec des résultats en double. La raison de la ligne du "Transformers.DistinctRootEntity" c'est pour filtrer par entité racine. il te faudra aussi la spécifier sur l'objet IQuery si tu utilises le hql.

    J'ai un peu de mal également à comprendre pourquoi tu met le hql directement dans le code ? perso, je préfère le sortir dans le mapping de manière a n'avoir qu'une grosse partie qui concerne la base de données.

    Bref, dans tous les cas, tu as de quoi avancer !

    Bonne après midi.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •