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 :

NHibernate très lent


Sujet :

NHibernate

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2009
    Messages : 35
    Par défaut NHibernate très lent
    Bonjour à tous

    Le context : je voudrais créer un DLL spécialiser dans l'accés aux données d'une DB Oracle :

    DBConnectionManager :
    • ConnectionManager : Class qui se charge de créer une connection vers la base oracle (DbConnection)
    • FluentConfiguration : Class qui configure NHibernate (via Fluent NHibernate) et Singleton qui me renvoie une Session NHibernate (ISession)
    • Class de mapping + entités (via Fluent NHibernate).


    DataAccessLayer :
    • Repository : fait appel à la session de la class que me configure NHibernate
    • ContactDAO : Class spécialisé dans les transactions que je dois exécuter avec un Contact


    Pour chacune des classes j'ai un projet test (NUnit) et c'est MEGA LENT quand je fais appel a une donnée... ma question est : qqu'un a t'il une idée du pourquoi ?

    Si vous voyez qque chose de pas logique dans l'architecture ou que je peux mieux faire n'hésitez pas à faire des remarques. Je ne suis pas vraiment à l'aise.

    Diplomegalo

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Y'a des milliers de raisons pour lesquelles NHibernate peut être lent... Sans le code qui est lent, c'est dur de deviner

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2009
    Messages : 35
    Par défaut
    Bonjour

    Ok j'avais tellement de doutes que je pensais que le problème aurait pour origine l'architecture.

    Etape 2 : le code. Un tout grand merci pour votre aide et bonne journée.

    DBConnectionManager :

    Connection + gestion de session

    Code C# : 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
     
    public class FluentConfiguration
        {
            private static ISessionFactory _sessionFactory;
     
            public static ISession Session {
                get {
                    if (FluentConfiguration._sessionFactory == null){
                        _sessionFactory = CreateSessionFactory();
                    }
     
                    return _sessionFactory.OpenSession();
                }
            }
     
            private static ISessionFactory CreateSessionFactory() {
                var cfg = OracleClientConfiguration.Oracle10
                    .ConnectionString( c => c.Is(Properties.ConnectionStrings.Default.Test.ToString()));
     
                return Fluently.Configure()
                    .Database(cfg)
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Contact>())
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Person>())
                    .BuildSessionFactory();
            }
        }

    Entité

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        public class Contact
        {
            public virtual string Id { get; private set; }
            public virtual string Firstname { get; set; }
            public virtual string Lastname { get; set; }
     
            public virtual IList<Person> Person { get; private set; }
     
     
            public Contact() {
                Person = new List<Person>();
            }        
        }

    Mapping

    Code C# : 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
     
    public class ContactMap : ClassMap<Contact>
        {
            public ContactMap()
            {
                Table("CONTACT");
     
                Id(x => x.Id, "contactid");
                Map(x => x.Firstname, "firstname");
                Map(x => x.Lastname, "lastname");
     
                HasMany(x => x.Person)
                    .Not.LazyLoad()
                    .KeyColumn("contactid")
                    .Inverse();
            }
        }

    DataAccessLayer

    Repository

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public class Repository
        {
            public static T GetById<T>(object id)
            {
                using (ISession session = DBConnectionManager.FluentConfiguration.Session)
                {
                    return session.Get<T>(id);
                }
            }
        }

    Test

    Code C# : 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
     
    [TestFixture]
        public class RepositoryTest
        {   
            [Test]
            public void GetById_Test1() {
                Contact contact = Repository.GetById<Contact>("CCxxxxxxxx51");
                Assert.AreEqual(contact.Id, "CCxxxxxxxx51");
            }
     
            [Test]
            public void GetById_Test2() {
                Contact contact = Repository.GetById<Contact>("CCxxxxxxxx51");
                Assert.AreEqual(contact.Person[0].ContactName, "NOM, PRENOM");
                Assert.AreEqual(contact.Person[0].Contact.Id, "CCxxxxxxxx51");
            }
        }

    Un tout grand merci pour votre aide et bonne journée.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2009
    Messages : 35
    Par défaut
    Je viens de débuger mon code. C'est le Get qui prend vraiment beaucoup de temps (plus de 10 sec).

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    return session.Get<T>(id);

    Si vous avez des remarques, elles sont les bienvenues

    ++

  5. #5
    Membre très actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Par défaut
    Salut,

    Tout d'abord je n'utilise pas Fluent, donc il possible/probable que je dise n'importe quoi...

    Une question, dans ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                return Fluently.Configure()
                    .Database(cfg)
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Contact>())
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Person>())
                    .BuildSessionFactory();
    Tu ne spécifies pas de lifecycle ou autre chose, du coup je me pose la question, dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (FluentConfiguration._sessionFactory == null){
    Ce test renvoie-t-il une seule fois false ?

    Car parmi les choses couteuses en nhibernate il y a le buildSessionFactory...

    Bonne chance.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2009
    Messages : 35
    Par défaut
    Bonjour à tous

    Tout d'abord merci pour votre aide et vos réponses.

    En ce qui concerne la création du ISessionFactory, en effet ce test renvoie une seul fois false. J'ai pu lire dans certains articles que le ISessionFactory était très lourd lors de la création et que le ISession était utilisé comme UOW. J'articule donc mon développement autour de ces concepts.

    J'ai effectué plusieurs tests à la suite l'un de l'autre et je n'économise pas vraiment de temps.

    Cependant je viens de faire une découverte : lorsque j'utilise l'ICriteria pour cibler mon information dans la base, j'économise du temps. Vous me direz : "bien vu l'aveugle ! ". Oui mais quand même je passe du simple au... 60 fois plus longtemps .

    Voici l'exemple :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public static int GetScoring(string contactId) {
        return Repository.GetById<Contact>(contactId).Screening.Score;
    }

    et avec criteria

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public static int GetScoring_Criteria(string contactid) {
        using (ISession session = FluentConfiguration.Session) {
            ICriteria criteria = session.CreateCriteria<Screening>();
            IList<Screening> sc = criteria.Add(Expression.Eq("Id", contactid)).List<Screening>();
            return sc[0].Score;
        }
    }

    Je me dis donc que la faute doit venir du nombre d'information que je fais remonter. Je vais donc essayer de jouer avec le LazyLoad.

    Je clôturerai ce topic si les résultats sont concluant avec le LazyLoad.

    Encore merci pour votre aide

    Bien à vous

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

Discussions similaires

  1. BDD sur réseau très très très lent...
    Par ericain dans le forum Access
    Réponses: 12
    Dernier message: 20/02/2015, 18h17
  2. Ouverture et fermeture de base très lent...
    Par Tofdelille dans le forum Installation
    Réponses: 6
    Dernier message: 19/09/2006, 19h51
  3. [Lomboz] Editeur jsp très lent
    Par lr dans le forum Eclipse Java
    Réponses: 10
    Dernier message: 29/01/2005, 20h43
  4. SQL Server trés lent
    Par arwen dans le forum MS SQL Server
    Réponses: 18
    Dernier message: 07/11/2003, 15h45

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