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

Débats sur le développement - Le Best Of Discussion :

Martin Fowler sur "la haine des ORM"


Sujet :

Débats sur le développement - Le Best Of

  1. #1
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut Martin Fowler sur "la haine des ORM"
    Bonjour,

    Je suis tombé par hasard sur cet article en parcourant le net :
    http://java.dzone.com/articles/martin-fowler-orm-hate

    ou M. Martin Fowler, un célèbre auteur de bouquin, répond aux nombreux anti-ORM du net qui disent être retournés au pur SQL après s'être essayé à des outils tels qu'hibernate ou active record.
    Vous remarquerez qu'on tombe assez souvent sur ce genre de témoignage en parcourant stackoverflow.

    MF explique que le mapping objet relationnel est un problème complexe qui ne peut pas avoir de réponse simple. Certes les ORMs offrent une abstraction, cette abstraction a un coût et la maîtrise de ces outils ne s'acquière pas facilement. S'ils ne sont pas la solution parfaite à tout, ils permettent bien souvent de se défaire d'une très grosse quantité de code répétitif (du CRUD typiquement) ce qui peut représenter parfois jusqu'à 80% des interactions DB.
    L'erreur selon lui, est d'attendre le 100% de leur part. Et c'est justement ces 20% restant qui demandent beaucoup d'attention et qui provoquent les critiques sévères à l'encontre des ORM, là où les connaissances plus poussées en relationnel deviennent nécessaires.

    Donc ces outils sont parfois des usines à gaz, ils sont parfois lents mais au fond ils sont surtout le plus souvent mal utilisés. (Je me souviens d'un forumeur BA.F de développez.com disant dans un vieux topic qu'hibernate était sans doute le framework le plus mal utilisé de la planète).

    C'est en gros le point de vue de notre ami MF : c'est pas parfait, mais ça résout bien des problèmes.

    Et vous :

    Utilisez-vous un ORM ou un outil d'accès aux données, par votre propre choix ou dicté par votre environnement d'entreprise?
    Avez-vous eu du mal à l'utiliser correctement, avez-vous regretté votre choix?
    Mélangez-vous les 2 approches (par exemple un ORM pour tout ce qui est CRUD/plomberie et le SQL a mano pour ce qui est vraiment exigeant).

  2. #2
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par _skip Voir le message
    Utilisez-vous un ORM ou un outil d'accès aux données, par votre propre choix ou dicté par votre environnement d'entreprise?
    Comme beaucoup dans l'écosystème Java, j'utilise Hibernate. C'est un héritage d'un framework de mon client. Pour avoir réaliser des applications sans, je rejoins l'avis de Martin Fowler, que ca fait gagner un temps non-négligeable, sans parler du risque d'erreur pour les aspects les plus simples et les plus répétitifs, CRUD et transformation SQL -> Objet (et inversement).
    Cependant il est vrai qu'on perd la main sur beaucoup d'aspects comme la génération des requêtes. Cependant j'ai trouver une solution assez simple et qui marche assez souvent, c'est de mapper des vues de bases de données.
    Sinon beaucoup de ces framework permettent d'écrire des requêtes SQL et de mapper les résultats.

    Citation Envoyé par _skip Voir le message
    Avez-vous eu du mal à l'utiliser correctement, avez-vous regretté votre choix?
    Personnellement non, mais il m'arrive de faire régulièrement du support. Je fais généralement deux constats, l'outil est mal utilisé mais surtout ses bases ne sont pas comprises/maitrisées. Pour la plupart un ORM est un outil magique qu'il suffit de savoir qu'il va générer la transformation Objet-SQL sans trop se soucier du comment et encore moins des implications.

    Citation Envoyé par _skip Voir le message
    Mélangez-vous les 2 approches (par exemple un ORM pour tout ce qui est CRUD/plomberie et le SQL a mano pour ce qui est vraiment exigeant).
    Ca m'arrive dans certains projets mais c'est plus par flemme de faire les mappings, je suis pas fan du pattern "DTO". Ensuite la génération dynamique de requête SQL est plus simple que le langage de requête orienté objet.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  3. #3
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    Mais Martin Fowler n'est-il pas "contre" le CRUD la plupart du temps ?...
    Il me semble que c'est lui qui racontait il y a quelques années que les devs ne devraient faire du CRUD que quand cela est sémantiquement correct de le faire.

  4. #4
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Ca serait contraire à l'Active Record ...

    De plus, il n'y a pas de question de jugement concernant le CRUD, seulement que les CRUD (c'est souvent nécessaire à un moment ou à un autre), est une tâche extrêmement répétitive et que les ORMs le font très bien.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  5. #5
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Ca m'arrive dans certains projets mais c'est plus par flemme de faire les mappings, je suis pas fan du pattern "DTO". Ensuite la génération dynamique de requête SQL est plus simple que le langage de requête orienté objet.
    Personne n'est fan de DTO mais c'est un choix qui s'impose de lui-même bien souvent lorsqu'on a tout à coup une Ui, ou plus simplement car on sait ce qui se passe lorsqu'un POJO hibernate dépasse la durée de vie de sa session et doit être sérialisé (pour ceux qui savent pas : plein de problèmes).

    Pour moi les ORMs peuvent résulter de 2 buts :

    - Eviter le recours au SQL à mano, ce qui veut pas dire que la connaissance SQL n'est soudainement plus nécessaire, bien au contraire.

    - Modéliser les relations entre les objets en restant le plus OO possible, jusqu'à un certain point. Car passé un stade il devient difficile d'avoir un compromis satisfaisant entre abstraction du modèle relationnel et performance.
    J'aurai aimé que ce débat est lieu dans cette discussion.

    Cet article illustre à petite échelle le problème du recours parfois inévitable au DTO.
    http://gregbeech.com/blog/service-or...e-applications

  6. #6
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par _skip Voir le message
    Personne n'est fan de DTO mais c'est un choix qui s'impose de lui-même bien souvent lorsqu'on a tout à coup une Ui, ou plus simplement car on sait ce qui se passe lorsqu'un POJO hibernate dépasse la durée de vie de sa session et doit être sérialisé (pour ceux qui savent pas : plein de problèmes).
    Réduire un POJO à la durée de vie de la session Hibernate/JPA est une très bonne chose pour les applications Web, particulièrement si elles fonctionnent en Cluster. Ca oblige également à réduire la taille de la session HTTP.

    Citation Envoyé par _skip Voir le message
    - Eviter le recours au SQL à mano, ce qui veut pas dire que la connaissance SQL n'est soudainement plus nécessaire, bien au contraire.
    C'est bien parfois le problème, les gens oublient que ca génère du SQL ! Cependant, il faut une certaine habitude pour penser à la fois en SQL et en "OQL".

    Citation Envoyé par _skip Voir le message
    - Modéliser les relations entre les objets en restant le plus OO possible, jusqu'à un certain point. Car passé un stade il devient difficile d'avoir un compromis satisfaisant entre abstraction du modèle relationnel et performance.
    Normalement, avec le pattern "Identité", on devrait avoir quelque de très similaire à ce qu'on peut avoir en "mémoire", avec l'avantage d'avoir plein de points d'accès grâce aux indexes.
    Cependant j'avoue que les applications sur lesquelles je travaille sont plutôt simples.

    Je ne connaissais pas cette discussion, je manquerai pas d'y jeter un oeil

    Citation Envoyé par _skip Voir le message
    Cet article illustre à petite échelle le problème du recours parfois inévitable au DTO.
    http://gregbeech.com/blog/service-or...e-applications
    Pour une fois que tu links un petit article, je prendrais le temps de le lire en entier celui-là
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  7. #7
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Réduire un POJO à la durée de vie de la session Hibernate/JPA est une très bonne chose pour les applications Web, particulièrement si elles fonctionnent en Cluster. Ca oblige également à réduire la taille de la session HTTP.
    C'est aussi un cas où il est très facile de manager une session, puisque tu peux l'ouvrir dans un filtre, compter dessus tout au long de la requête et ensuite la fermer.
    Ainsi si tu ne fais pas d'effort pour essayer à tout prix de stocker ton pojo managé, tu peux le charger dans le service, le passer à la couche supérieure, l'utiliser à fond dans ton UI quitte à lazy loader 2 ou 3 graphes, et finalement le sauver ou le laisser mourir.

    C'est 200 fois plus casse-gueule dans un fat client, puisque ton service devra bien décider ce qu'il fait de la session après t'avoir retourné ton pojo, et s'il la ferme, ton objet tout gentil devient une bombe atomique.

    Je me suis toujours demandé comment les autres gens réglaient ce problème, les seuls que j'ai trouvés finalement utilisaient une session par application ou en threadlocal, malgré que ce soit assez dangereux.


    Je ne connaissais pas cette discussion, je manquerai pas d'y jeter un oeil

    Pour une fois que tu links un petit article, je prendrais le temps de le lire en entier celui-là
    La discussion a malheureusement viré un peu sur la représentation object en C et on a assez peu parlé des stratégies et enjeux du domain model objet. Dommage car j'aime bien échanger des points de vue avec d'autres développeurs, confronter ses idées ça fait souvent progresser. Puis ça change des sujets à la "Euh un bon développeur tu vois... c'est, c'est un bon développeur quoi...".

  8. #8
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par _skip Voir le message
    C'est aussi un cas où il est très facile de manager une session, puisque tu peux l'ouvrir dans un filtre, compter dessus tout au long de la requête et ensuite la fermer.
    Ainsi si tu ne fais pas d'effort pour essayer à tout prix de stocker ton pojo managé, tu peux le charger dans le service, le passer à la couche supérieure, l'utiliser à fond dans ton UI quitte à lazy loader 2 ou 3 graphes, et finalement le sauver ou le laisser mourir.

    C'est 200 fois plus casse-gueule dans un fat client, puisque ton service devra bien décider ce qu'il fait de la session après t'avoir retourné ton pojo, et s'il la ferme, ton objet tout gentil devient une bombe atomique.

    Je me suis toujours demandé comment les autres gens réglaient ce problème, les seuls que j'ai trouvés finalement utilisaient une session par application ou en threadlocal, malgré que ce soit assez dangereux.
    En fait j'ai remarqué que souvent les gens oublient la notion de transaction métier.
    Un client lourd ne devrait pas agir différemment qu'une application web. Le client fait des manipulations sur le formulaire et soumet le formulaire. La notion de requête est plus floue mais elle existe. Elle devrait ressembler à quelque chose comme "UI Command Service *some work* ( DAO) Business notification UI View update", ce dernier rappelant éventuellement la couche Service pour obtenir des informations qui seront éventuellement demandée à la couche DAO.

    Garder la même session ne fait que forcer le maintien de la connexion, ca revient à faire un pool de connexion avec une taille minimale de 1. Autant pour une application centralisée ca ne pose pas de problèmes, ca fera jamais qu'un minimum de connexion par noeud du cluster, plus quelques connexions supplémentaires pour les batchs et autres services d'administration (monitoring, suivi de production, etc). Par contre dans des architectures très réparties (type client lourd), on peut vite saturer le serveur de base de données, voir atteindre le nombre de limite de connexion globale ou pour un login donné.

    Donc même dans un client lourd, il ne faut pas hésiter à utiliser des sessions Stateless, detach et merge.
    Bon c'est surtout du jargon Hibernate, alors je sais pas trop quelles sont les termes génériques afin que chacun puisse comprendre ?


    Citation Envoyé par _skip Voir le message
    La discussion a malheureusement viré un peu sur la représentation object en C et on a assez peu parlé des stratégies et enjeux du domain model objet. Dommage car j'aime bien échanger des points de vue avec d'autres développeurs, confronter ses idées ça fait souvent progresser.
    Entièrement d'accord, d'ailleurs c'est un peu ce qui m'a mené dans cette partie du forum.

    Citation Envoyé par _skip Voir le message
    Puis ça change des sujets à la "Euh un bon développeur tu vois... c'est, c'est un bon développeur quoi...".
    Je ne peux que plussoyer
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  9. #9
    Membre émérite
    Inscrit en
    Janvier 2011
    Messages
    805
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Janvier 2011
    Messages : 805
    Points : 2 918
    Points
    2 918
    Par défaut
    Citation Envoyé par _skip Voir le message
    Utilisez-vous un ORM ou un outil d'accès aux données, par votre propre choix ou dicté par votre environnement d'entreprise?
    Oui, dicté par l'entreprise.

    Citation Envoyé par _skip Voir le message
    Avez-vous eu du mal à l'utiliser correctement, avez-vous regretté votre choix?
    Oui, comme beaucoup de monde je pense. Qui n'a pas bataillé pour dompter son ORM et arriver à lui faire faire à peu près ce qu'on souhaite ?

    Citation Envoyé par _skip Voir le message
    Mélangez-vous les 2 approches (par exemple un ORM pour tout ce qui est CRUD/plomberie et le SQL a mano pour ce qui est vraiment exigeant).
    Oui, et notamment pour toutes les requêtes critiques en termes de performances. Quand on prend des outils comme (N)Hibernate, il est dangereux de lui déléguer aveuglément des requêtes qui ramènent de gros graphes d'objets. On a ponctuellement besoin d'écrire du HQL un peu tuné ou carrément de zapper l'ORM en passant par du SQL.

    Mais j'accepte ce prix et je suis 100% d'accord avec l'analyse de Fowler : la plupart des gens se sont tellement mis dans la tête que leur ORM allait faire la bouffe, le café et le ménage qu'au moindre souci, ils le jettent à la poubelle en oubliant tous les services qu'il leur rend.

  10. #10
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Si j'ose demander, c'est quel type d'application principalement?
    Du web service? Du client lourd?

    Pour en revenir à hibernate, perso je n'utilise pas cet outil car ce serait trop risqué et l'un des principaux avantages qu'il procure, soit la génération de graphe est inutilisable dans mon projet car presque indissociable du lazy loading lors de l'utilisation en condition réelle. Or notre service doit maîtriser exactement les chargements qu'il effectue en DB, sans compter que la durée de vie des objets chargés est très variable.

    J'utilise donc mybatis, très orienté SQL, qui est certes un gros soulagement par rapport à du jdbc pur mais cependant il faut admettre que ça a des contraintes, mappage à la main vite pénible dans le cas de graphes et risque non négligeable de régression en cas de modification de schéma.

  11. #11
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par _skip Voir le message
    Si j'ose demander, c'est quel type d'application principalement?
    Du web service? Du client lourd?
    Je réalise quasi-exclusivement des applications Web (avec ou sans WS). J'ai bien une application en client lourd, mais les accès à la base de données sont effectués par un serveur "business". Dans celle-ci nous utilisons Apache Commons DbUtils pour réaliser des mappings ultra-simpliste et tout quasiment hardcodé. Et dans cette application, nous utilisons différents type de SGBD (H2, MySQL et Oracle principalement) et je suis qu'un plugin donc le choix est imposé.

    Citation Envoyé par _skip Voir le message
    Pour en revenir à hibernate, perso je n'utilise pas cet outil car ce serait trop risqué et l'un des principaux avantages qu'il procure, soit la génération de graphe est inutilisable dans mon projet car presque indissociable du lazy loading lors de l'utilisation en condition réelle. Or notre service doit maîtriser exactement les chargements qu'il effectue en DB, sans compter que la durée de vie des objets chargés est très variable.

    J'utilise donc mybatis, très orienté SQL, qui est certes un gros soulagement par rapport à du jdbc pur mais cependant il faut admettre que ça a des contraintes, mappage à la main vite pénible dans le cas de graphes et risque non négligeable de régression en cas de modification de schéma.
    Je reconnais que toutes les applications sur lesquelles je travaille, les graphes d'objets mappés en BDD sont très simples. Il y a très peu de liaisons, voir quasiment aucune. La plupart des liens se font fonctionnellement et donc avec une nouvelle requête.

    Ce que je trouve dommage, c'est qu'on peut pas exprimé facilement le lazy-loading au chargement des données. Le seul moyen que je connaisse c'est de tout mettre en lazy (ou aucun chargement) et d'utiliser une requête HQL dans laquelle on précise le contenu de la collection.

    En matière de personnalisation des requêtes, je trouve qu'iBatis est vraiment intéressant. Le truc chiant c'est de se tartiner systématiquement toutes les requêtes même les plus simples ... Ca permet également de faire très "efficacement" des applications multi-SGBD, car il faut avouer que même si c'est possible avec Hibernate, je ne suis pas persuadé que cela fonctionne parfaitement. L'art de l'ORM consiste souvent à trouver un compromis entre le design des classes et celui de la BDD, hors si on change de BDD on a pas nécessairement les mêmes contraintes et il vaut mieux avoir un mapping propre à chaque SGBD.

    En revanche, quid des fonctionnalités avancées offertes par les ORMs avec des solutions comme iBatis ? Par exemple, la gestion du cache de second niveau ?
    Même si j'avoue que ce genre de cache n'est pas très utilisé sur mes applications et que les caches les plus critiques sont gérés "à la mano" avec le couple EhCache+AspectJ.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  12. #12
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Ce que je trouve dommage, c'est qu'on peut pas exprimé facilement le lazy-loading au chargement des données. Le seul moyen que je connaisse c'est de tout mettre en lazy (ou aucun chargement) et d'utiliser une requête HQL dans laquelle on précise le contenu de la collection.
    Donc ca oblige bien souvent tes couches supérieures à avoir conscience, ou peut être même à fournir des "hints" sur la stratégie à adopter selon que tu penses avoir besoin des entités en relation ou non.
    C'est une des raisons pour laquelle je pense que l'abstraction totale de la persistance est un leurre, comme toutes ces théories académiques du 3/tiers ou on peut remplacer la source de données par un fichier XML ou un webservice, dans la pratique c'est pas un autre tiers mais une autre application.
    On encourage trop les gens à faire de la surabstraction, à un point où ça en est pénalisant, voire nuisible.


    Citation Envoyé par Nemek Voir le message
    En revanche, quid des fonctionnalités avancées offertes par les ORMs avec des solutions comme iBatis ? Par exemple, la gestion du cache de second niveau ?
    Même si j'avoue que ce genre de cache n'est pas très utilisé sur mes applications et que les caches les plus critiques sont gérés "à la mano" avec le couple EhCache+AspectJ.
    Il y a des mécaniques de caching dans mybatis, avec différentes solutions pluggable mais je ne m'en sers pas.

    La mémoire est critique dans mon projet et je fais beaucoup de grosses requêtes qui m'obligent déjà à avoir recours à des curseurs DB pour les charger ligne à ligne, donc je peux pas accepter qu'un mécanisme automatique maintienne en mémoire des objets dont je n'ai pour 80% rien à cirer.

    J'ai un cache d'application totalement home made et dédié, qui va loin dans l'optimisation, au point d'éviter de recréer des "String" qu'il connaît déjà au chargement de ses indexs pour éviter d'avoir plusieurs copie d'un même buffer en mémoire.

  13. #13
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par _skip Voir le message
    Donc ca oblige bien souvent tes couches supérieures à avoir conscience, ou peut être même à fournir des "hints" sur la stratégie à adopter selon que tu penses avoir besoin des entités en relation ou non.
    C'est une des raisons pour laquelle je pense que l'abstraction totale de la persistance est un leurre, comme toutes ces théories académiques du 3/tiers ou on peut remplacer la source de données par un fichier XML ou un webservice, dans la pratique c'est pas un autre tiers mais une autre application.
    On encourage trop les gens à faire de la surabstraction, à un point où ça en est pénalisant, voire nuisible.
    Voilà un autre débat intéressant, la principale justification c'est, je pense, d'organiser le code, les idées et le design.
    Bien avant la "switchabilité". D'ailleurs ce dernier est même le pire argument qui soit. Pourquoi fait un truc évolutif/remplaçable, puisque de toutes façons il faudra coder pour l'intégrer ? Autant économiser 5 jours de conception et presque le double de codage à la première version et n'en dépenser que la moitié le jour où il faut effectivement remplacer.

    Le fait d'organiser permet de limiter l'effet code/design spaghetti et permet également à la plupart des gens de comprendre et rechercher rapidement une information ou un bout de code.
    Cependant l'accès au donnée repose en totalité sur son organisation qui elle-même repose en grande partie sur le "métier". Il est donc illusoire de bien séparer la couche "Service" qui doit contenir la logique métier et la couche "Données" qui permet d'accéder à l'information.
    D'ailleurs si en revient à conception orienté-objet c'est même le contraire qui faudrait faire. Le principe de l'objet est de rassembler données et comportements qui sont liés. On en revient à quelque chose des très MERISien, avec d'un côté les données et de l'autre les traitements.

    De manière générale, je suis partisan d'une organisation simple et nécessaire. A savoir d'un côté, une séparation "logique" qui permet l'accès rapide au code/design et de l'autre faire simple (ex: pas de couches) puis "refactorer" lorsque c'est nécessaire.

    Citation Envoyé par _skip Voir le message
    Il y a des mécaniques de caching dans mybatis, avec différentes solutions pluggable mais je ne m'en sers pas.
    En fait je pensais majoritairement à la façon de générer le graphe. Dans les ORMs il y a deux stratégies pour générer les "liens", soit une deuxième requête, soit par un join. Généralement quand on fait un join, un "même" objet peut être présent plusieurs fois. C'est particulièrement le cas pour les relations "Many-To-One" (filspère). Dans ce cas, pour que le graphe soit bon, il faut bien garder le père qui a été chargé durant le traitement de la requête. Mais il faut aussi que les autres requêtes de la même transaction, chargent le même objet sinon ca n'aurait pas de sens ...

    Citation Envoyé par _skip Voir le message
    La mémoire est critique dans mon projet et je fais beaucoup de grosses requêtes qui m'obligent déjà à avoir recours à des curseurs DB pour les charger ligne à ligne, donc je peux pas accepter qu'un mécanisme automatique maintienne en mémoire des objets dont je n'ai pour 80% rien à cirer.
    iBatis permet de faire ce genre de trucs ?

    Moralité, le meilleur système c'est celui qui sera le plus souple par rapport aux besoins ! Ce qui m'inspire la question suivante : est-ce infaisable avec Hibernate (ou équivalent) ?

    J'ai un cache d'application totalement home made et dédié, qui va loin dans l'optimisation, au point d'éviter de recréer des "String" qu'il connaît déjà au chargement de ses indexs pour éviter d'avoir plusieurs copie d'un même buffer en mémoire.
    ... Et dire que j'ai une application qui consomme 32Gb de RAM Bon ok c'est sûrement conçu et codé avec les pieds ! Cependant pour le client, le calcul est simple : une nouvelle unité matérielle (un serveur, un processeur, une barrette de mémoire) coutera souvent moins cher qu'un seul jour de dev.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  14. #14
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Voilà un autre débat intéressant, la principale justification c'est, je pense, d'organiser le code, les idées et le design.
    Bien avant la "switchabilité". D'ailleurs ce dernier est même le pire argument qui soit. Pourquoi fait un truc évolutif/remplaçable, puisque de toutes façons il faudra coder pour l'intégrer ? Autant économiser 5 jours de conception et presque le double de codage à la première version et n'en dépenser que la moitié le jour où il faut effectivement remplacer.
    C'est tout à fait ce que je pense, pour moi le 3 tiers c'est une façon générale de réfléchir, pas un concept en pierre.

    Citation Envoyé par Nemek Voir le message
    En fait je pensais majoritairement à la façon de générer le graphe. Dans les ORMs il y a deux stratégies pour générer les "liens", soit une deuxième requête, soit par un join. Généralement quand on fait un join, un "même" objet peut être présent plusieurs fois. C'est particulièrement le cas pour les relations "Many-To-One" (filspère). Dans ce cas, pour que le graphe soit bon, il faut bien garder le père qui a été chargé durant le traitement de la requête. Mais il faut aussi que les autres requêtes de la même transaction, chargent le même objet sinon ca n'aurait pas de sens ...
    Je crois que je vois à quoi tu fais référence, soit le chargement d'un graphe en plusieurs requêtes en laissant l'ORM "recoudre" les 2 choses pour éviter d'avoir des jointures qui aboutissent à des produits cartésiens.
    Non je ne connais pas de concept similaire en mybatis.

    Citation Envoyé par Nemek Voir le message
    iBatis permet de faire ce genre de trucs ?

    Moralité, le meilleur système c'est celui qui sera le plus souple par rapport aux besoins ! Ce qui m'inspire la question suivante : est-ce infaisable avec Hibernate (ou équivalent) ?
    Oui, tu as des overloads qui retournent des listes et aussi d'autres qui te permettent de donner ton propre RowHandler dont la méthode handle est appelée pour chaque ligne de ton resultset.

    ... Et dire que j'ai une application qui consomme 32Gb de RAM Bon ok c'est sûrement conçu et codé avec les pieds ! Cependant pour le client, le calcul est simple : une nouvelle unité matérielle (un serveur, un processeur, une barrette de mémoire) coutera souvent moins cher qu'un seul jour de dev.
    Le problème c'est que chez nous, c'est nous qui hébergeons les solutions dans 80% des cas donc on gagne à parquer le plus possible de clients par VM, de plus c'est un argument de vente que de pouvoir être utilisé sur des VPS standards (linux, 2048 ram) peu onéreux.
    On a du rester modeste en infrastructure afin de ne pas exploser les prix du service.

  15. #15
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par _skip Voir le message
    Je crois que je vois à quoi tu fais référence, soit le chargement d'un graphe en plusieurs requêtes en laissant l'ORM "recoudre" les 2 choses pour éviter d'avoir des jointures qui aboutissent à des produits cartésiens.
    Non je ne connais pas de concept similaire en mybatis.
    D'ailleurs comment sont générés les relations dans MyBatis ? Il y a un mécanisme "automatique" (par exemple, appeler la session.get(Child.class, childId) ?

    Citation Envoyé par _skip Voir le message
    Oui, tu as des overloads qui retournent des listes et aussi d'autres qui te permettent de donner ton propre RowHandler dont la méthode handle est appelée pour chaque ligne de ton resultset.
    Donc pourquoi ne pas utiliser Hibernate ?!


    Citation Envoyé par _skip Voir le message
    Le problème c'est que chez nous, c'est nous qui hébergeons les solutions dans 80% des cas donc on gagne à parquer le plus possible de clients par VM, de plus c'est un argument de vente que de pouvoir être utilisé sur des VPS standards (linux, 2048 ram) peu onéreux.
    On a du rester modeste en infrastructure afin de ne pas exploser les prix du service.
    Ca me semble pas être une mauvaise idée. Rien que pour le développement. Sur le projet dont je te parle, on est obligé de monopoliser une machine pour le serveur, et tous les développeurs doivent se partager le même serveur ...
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  16. #16
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Citation Envoyé par Nemek Voir le message
    D'ailleurs comment sont générés les relations dans MyBatis ? Il y a un mécanisme "automatique" (par exemple, appeler la session.get(Child.class, childId) ?
    Non, il y a du lazy loading de base mais c'est primitif, sinon foireux. Autrement c'est à toi de te débrouiller, ou alors tu acceptes une approche moins full OO et tu ne relies que les entités indissociables.
    Par défaut, mybatis peut mapper des resultsets avec des objet java et éventuellement fabriquer un graphe avec une jointure. Par contre il se contente d'exécuter le SQL que tu lui files et de fabriquer des objets selon les maps que tu as défini, c'est tout.
    C'est vraiment pas magique, mais c'est puissant.

    Donc pourquoi ne pas utiliser Hibernate ?!
    Le truc du rowhandler c'est un feature de mybatis, pas d'hibernate, je sais pas si c'est possible en hibernate.

    Mais pour répondre à la question, c'est parce qu'on a commencé avec du JDBC pur et du dbutils et qu'ensuite, passer à du mybatis était moins compliqué que tout repenser en hibernate. Ensuite, il aurait fallu apprivoiser l'outil, connaître tous les pièges (et il y en a), s'arranger pour que les objets obtenus puissent être sérializés, plein de choses de ce genre qui font que c'était plus simple de rester avec notre SQL micro-tuné.

    Ca me semble pas être une mauvaise idée. Rien que pour le développement. Sur le projet dont je te parle, on est obligé de monopoliser une machine pour le serveur, et tous les développeurs doivent se partager le même serveur ...
    Ben c'est un choix qui a causé son lot de sueur, car on en a passé du temps à optimiser ce modèle et on s'est privé de nombre de facilités.

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/02/2005, 20h32
  2. Erreur sur une fonction avec des paramètres
    Par Elois dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 05/05/2004, 21h00
  3. Réponses: 7
    Dernier message: 21/04/2004, 17h16

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