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

Java Discussion :

L’ORM serait-il une « grosse erreur » ?


Sujet :

Java

  1. #1
    Expert éminent sénior

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2014
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2014
    Messages : 194
    Points : 12 291
    Points
    12 291
    Par défaut L’ORM serait-il une « grosse erreur » ?
    L’ORM serait-il une « grosse erreur » ?
    Selon un développeur, « l’ORM est un anti-pattern qui ne devrait pas exister »

    Il existe plusieurs design patterns utilisés dans la programmation orientée objet, et certains tellement utilisés qu’ils deviennent presque incontournables lorsqu’on veut apprendre le développement. L’Object Relationnal Mapping (ORM) est l’un de ces patterns à succès. Il permet d’accéder à une base de données relationnelle à partir d’objets. On peut le résumer comme une technique qui crée l’illusion d’une base de données orientée objet à partir d’une base de données relationnelle.

    Ce modèle est implémenté dans plusieurs langages de programmation aujourd’hui à tel point qu’il devient une référence dans les livres. Toutefois, dans un article, Yegor Bugayenko, Directeur de technologie à Teamed.io, déclare que « l’ORM est un anti-pattern terrible qui viole tous les principes de la programmation orientée objet ».

    Ce n’est pas la première fois que quelqu’un critique l’ORM. Le débat est long et ne date pas d'hier. On lui avait déjà reproché d’être techniquement limité, faible en performances et difficile à apprendre. Toutefois, pour Yegor Bugayenko, l'idée derrière l’ORM est fausse. Selon lui, « son invention était peut-être la deuxième grosse erreur en POO après la référence NULL ».

    La raison qu’il donne est simple ; au lieu d’encapsuler l’interaction avec la base de données dans un objet et fournir par conséquent un point d'entrée unique, il fait l’inverse : il définit les routines qui permettent de communiquer avec la base dans l’objet ORM tandis que les données sont extraites « dans la chose que nous ne pouvons même pas appeler un objet ». Ce qui rend la détection des erreurs plus difficile. Mais en plus, « le SQL n’est pas caché » ce qui ajoute au programmeur la contrainte d’en connaître la syntaxe.


    Figure : comparaison entre 1) technique utilisée par l'ORM, 2) technique utilisée par les SQL-speaking objects

    Selon lui, la solution serait d’encapsuler le tout dans un seul et même objet (comme décrit dans la figure). Cet objet, que Yegor Bugayenko appelle « SQL-speaking object », sera en charge de toutes les opérations et permettra de cacher tous les détails de la communication avec la base de données : « Il n'y a pas de transactions, pas de sessions ou de factories. Nous ne savons même pas si ces objets sont en train de parler avec la base de données ou s’ils gardent toutes les données dans des fichiers textes ».

    Dans son article, il présente quelques exemples en insistant sur le fait que les SQL-speaking objects sont plus simples et respectent de loin les principes de l’orienté objet, à l’inverse de l’ORM « qui ne devrait exister dans aucune application, que ce soit une petite application web ou un gros système pour entreprise ».

    Source : DZone

    Et vous ?

    Êtes-vous d’accord avec l’avis de Yegor Bugayenko ? Pourquoi ?

  2. #2
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Je n'ai pas tout à fait compris l'intérêt de l'article publié par Bugayengo.

    Certes les ORM (je pense à l'approche JPA en particulier) :
    • apportent une surcouche qui ralentit le programme.
    • génèrent des requêtes SQL parfois aberrantes quand on observe au niveau débug.
    • ont pas mal de spécificités (notamment la gestion des transactions, quoi que... en activant le mode JTA on peut se passer des transactions)
    • ne sont pas adaptés pour créer des batchs
    • ne sont pas adaptés pour écrire des requêtes SELECT complexes

    ... mais pour une application web de gestion ou un blog par exemple, ils simplifient grandement l'écriture du code pour des opérations de types INSERT/UPDATE/DELETE et les SELECT simples.


    L'auteur crée la méthode suivante pour insérer un objet de type Post dans sa base :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      public Post add(Date date, String title) {
        return new PgPost(
          this.dbase,
          new JdbcSession(this.dbase)
            .sql("INSERT INTO post (date, title) VALUES (?, ?)")
            .set(new Utc(date))
            .set(title)
            .insert(new SingleOutcome<Integer>(Integer.class))
        );
      }
    En utilisant un ORM je fais juste ceci :

    L'auteur crée la méthode suivante qui retourne un iterable pour récupérer tous les objets de type Post dans sa base :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      public Iterable<Post> iterate() {
        return new JdbcSession(this.dbase)
          .sql("SELECT id FROM post")
          .select(
            new ListOutcome<Post>(
              new ListOutcome.Mapping<Post>() {
                @Override
                public Post map(final ResultSet rset) {
                  return new PgPost(rset.getInteger(1));
                }
              }
            )
          );
      }
    Je ne vois pas l'intérêt de récupérer tous les éléments d'une table, par contre en utilisant un ORM je peux récupérer un objet en particulier comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Post post = em.find(Post.class, monId);
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  3. #3
    Membre expérimenté Avatar de dfiad77pro
    Homme Profil pro
    Responsable Architecture logicielle
    Inscrit en
    Décembre 2008
    Messages
    541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable Architecture logicielle
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 541
    Points : 1 729
    Points
    1 729
    Par défaut
    Un ORM (je pense à Entity Framework que je connais mieux)
    peut aussi être utilisé conjointement avec d'autre méthodes ( proc stockée, etc.).

    On est même pas obliger d'utiliser la persistance tout le temps.

    J'ai de nombreux projets à flux importants qui utilisent un ORM et ne sont pas lents...
    Cela dit un ORM nécessite beaucoup d'expérience pour être utilisé de manière optimale dans une architecture complexe.
    Sa simplicité apparente est un leurre.


    Dire qu'une Techno est Anti-Patern, sans proposer mieux, c'est l'excuse à la mode

    ( je l'entends souvent de la part des dev Java à propos de C# sur les méthodes d'extension et Linq )

  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
    Génial, il propose l'idée de tout recoder à la main ?
    Je vois rien dans ce qu'il propose qui est une réelle différence avec le système actuel à part que le sien est complétement "figé" et lie complétement l'interface avec son interface de communication avec la base de données. Mais attendez .... ca ressemblerait pas à JPA avec les annotations ?

    Franchement quit à faire du SQL, autant partir sur MyBatis. Apache Cayenne me semble également intéressant mais je n'ai pas eu l'occasion de le mettre en pratique.



    Bon lisons l'article, "ne jugeons pas un livre à sa couverture" m'a-t-on dit.

    Citation Envoyé par Yegor Bugayenko
    I, being a reader of posts, have to deal with two components: 1) the ORM and 2) the "obtruncated" object returned to me. The behavior I'm interacting with is supposed to be provided through a single entry point, which is an object in OOP. In the case of ORM, I'm getting this behavior via two entry points — the ORM and the "thing", which we can't even call an object.

    Because of this terrible and offensive violation of the object-oriented paradigm, we have a lot of practical issues already mentioned in respected publications. I can only add a few more.
    La critique qu'il porte aux ORMs c'est juste son fonctionnement en mode service, dans ce cas il peut rajouter SOAP et REST dans le panier... Si quelqu'un a un réel argument contre la SOA, je veux bien l'entendre mais qu'on ne tienne pas un grief contre un ORM parce que c'est un service ...

    Citation Envoyé par Yegor Bugayenko
    SQL Is Not Hidden
    Le plus mauvais argument qui soit : je fais les choses mal alors c'est l'outil qui a un défaut. L'huile ca tâche alors retirons l'huile des moteurs ... Encore et toujours un problème de vision en "service". Le but du framework n'est pas d'implémenter la logique métier mais de l'utiliser pour implémenter la logique métier.
    Sinon il y a les applications Forms avec des procédures stockées. On serait presque à se demander pourquoi les Forms ne sont pas aussi populaires ...

    Citation Envoyé par Yegor Bugayenko
    Difficult to Test
    pour Hibernate, il n'y a aucune difficulté à bouchonner/simuler de telles interfaces. Mais laissons de côté l'utilisation d'un framework/langage en particulier. Comment compte-t-il simplifier cela en attaquant directement la base de données ? En bouchonnant/simulant toutes les interfaces JDBC ? Je vous laisse songer à la différence du nombre de méthode entre les interfaces Hibernate et celles de JDBC ...

    Citation Envoyé par Yegor Bugayenko
    What About Performance?
    Le monsieur nous propose une version qui interroge la base à chaque getter/setter ... A ce problème, il propose de rajouter une surcouche (encore et toujours non-agnostique) qui génère un cache. Il faudra compteur encore deux classes de plus pour un seul concept (entité/table/interface/objet de domaine).

    Citation Envoyé par Yegor Bugayenko
    What About Transactions?
    Il propose que chaque objet dispose de sa propre (sous-)transaction. Pourquoi pas, mais dans ce cas on reporte toute la responsabilité sur un unique objet quand parfois on veut traiter un ensemble. Encore une nouvelle instance à créer en perspective ...
    En alternative, il nous propose l'encapsulation dans un "Callable" comme si les transactions étaient nécessairement limité par appel d'un simple morceau de code quand parfois, une orchestration entre plusieurs systèmes ou délimité par un contexte (ex : une requête) est nécessaire.



    Bon l'article est bouclé et revenons aux problèmes posés par les ORMs.

    Citation Envoyé par Yegor Bugayenko
    I, being a reader of posts, have to deal with two components: 1) the ORM and 2) the "obtruncated" object returned to me.
    Solution proposée : au minimum deux composants très spécialisés par concept ... Je commente pas plus.

    Citation Envoyé par Yegor Bugayenko
    SQL Is Not Hidden
    Solution proposée : écrire soit même tout le SQL.
    Vous souhaitez ajouter le support d'une nouvelle base de données ? Il suffit de dupliquer toutes les classes existantes ...

    Citation Envoyé par Yegor Bugayenko
    Difficult to Test
    Solution proposée : bouchonner/simuler les concepts mais y a-t-il encore quelque chose à tester ? Sinon c'est tout JDBC qu'il vous faudra bouchonner/simuler ...

    Citation Envoyé par Yegor Bugayenko
    What About Performance?
    Au final compter 4-5 classes par concept et autant d'instance à créer pour chaque entrée. On rajoute un peu de requêtes crées à la volée sans aucun cache et ni même de support d'envoi groupé ("batch") des requêtes. C'est sûr que les ORMs ont de gros problèmes de performance ...
    Et quid de la performance de l'écriture d'une telle application ? A vu de nez, je dirais qu'en une semaine vous devriez avoir les "bases" d'un Pet Clinic fonctionnant sur unique SGBD. Choisissez bien dès le départ car pour en changer il va falloir revoir une bonne partie de vos classes.

    Voici une petite liste de petites contraintes que je retiens (je vous laisse proposer votre propre liste):
    1. Aucune cohérence assurée entre la transaction et le modèle mémoire.
    2. Aucune possibilité d'extension sur la façon de travailler avec un concept.
    3. Ajouter un champ nécessitera d'impacter au minimum 4-5 classes.
    4. Aucune piste pour gérer des mises à jour et les relations.


    Quid des griefs contre les ORMs:
    1. De mauvaises performances : le seul travaille de l'ORM c'est le mapping, et lui sera toujours nécessaire. Le reste est entre les mains de l'utilisateur avec une facilité pour les choses simples et des points d'extensions plus ou moins complexes pour les besoins spécifiques.
    2. Non-encapsulation totale du SQL : on travaille avec un SGBD et il faudra toujours faire avec. Les concepts sous-jacents s'appliquent également aux couches supérieures. Par ailleurs, je ne vois pas l'ORM comme un encapsulateur du relationnel mais comme un facilitateur pour joindre le monde relationnel et l'objet. Ceux qui le vendent comme une encapsulation sont d'aussi mauvais vendeur que notre auteur.



    Au final la vraie question, que veut-il encore nous vendre ? http://jdbc.jcabi.com/
    Si vous souhaitez vraiment une solution simple et efficace, je vous propose DbOom


    PS : Moi, je ne touche aucune rétro-commission sur la ventel'utilisation des solutions que je vous propose.
    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
    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 Gugelhupf Voir le message
    apportent une surcouche qui ralentit le programme.
    Ralentit par rapport à quoi ? Et quel impact chiffré ?

    Citation Envoyé par Gugelhupf Voir le message
    génèrent des requêtes SQL parfois aberrantes quand on observe au niveau débug.
    Il ne fait que ce que tu lui dis de faire ... Au pire, tu peux lui donner du SQL à manger.

    Citation Envoyé par Gugelhupf Voir le message
    ont pas mal de spécificités (notamment la gestion des transactions, quoi que... en activant le mode JTA on peut se passer des transactions)
    Je pense que les transactions sont le pire des exemples. Le "modèle" transactionnelle de JPA est le même que JDBC et que la base de données. Et je n'ai pas trop d'expérience avec d'autres systèmes transactionnels mais je suis à peu près sûr qu'ils respectent tous les principes suivants :
    1. Tout ou rien
    2. Toute conversation est transactionnelle, même si elle peut être implicite.
    3. Les transactions filles ne peuvent pas être validées mais elles peuvent être annulées, annulant ainsi toutes les filles (petites filles incluses) venant après.


    Citation Envoyé par Gugelhupf Voir le message
    ne sont pas adaptés pour créer des batchs
    Ca dépend du batch. Dès que tu veux transposer un modèle relationnel en modèle objet, un ORM a son utilité. Que ce soit à des fins de traitement massifs ou plus unitaire comme une requête (utilisateur, pas SQL).

    Citation Envoyé par Gugelhupf Voir le message
    ne sont pas adaptés pour écrire des requêtes SELECT complexes
    Je veux bien un exemple même abstrait. Dans la mesure où tu peux utiliser du SQL, la complexité ne sera pas bcp plus grande que le SQL.
    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

  6. #6
    Membre éprouvé
    Avatar de landry161
    Homme Profil pro
    C#,PHP,MySQL,Android...
    Inscrit en
    Juillet 2010
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : C#,PHP,MySQL,Android...

    Informations forums :
    Inscription : Juillet 2010
    Messages : 423
    Points : 1 059
    Points
    1 059
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Logan Mauzaize Voir le message
    Génial, il propose l'idée de tout recoder à la main?
    A mon avis ça sera vraiment pas évident

  7. #7
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par Logan Mauzaize Voir le message
    1. Ralentit par rapport à quoi ? Et quel impact chiffré ?

    2. Il ne fait que ce que tu lui dis de faire ... Au pire, tu peux lui donner du SQL à manger.

    3. Je pense que les transactions sont le pire des exemples. Le "modèle" transactionnelle de JPA est le même que JDBC et que la base de données. Et je n'ai pas trop d'expérience avec d'autres systèmes transactionnels mais je suis à peu près sûr qu'ils respectent tous les principes suivants :
    1. Tout ou rien
    2. Toute conversation est transactionnelle, même si elle peut être implicite.
    3. Les transactions filles ne peuvent pas être validées mais elles peuvent être annulées, annulant ainsi toutes les filles (petites filles incluses) venant après.


    [...]

    4. Je veux bien un exemple même abstrait. Dans la mesure où tu peux utiliser du SQL, la complexité ne sera pas bcp plus grande que le SQL.
    1. Un ami et moi avons créé un batch en utilisant JPA/Hibernate, et reproduit l'équivalent avec JDBC. JDBC est plus rapide, déjà le temps d'initialisation de ce dernier est négligeable par rapport à JPA/Hibernate. Pour les chiffres on ne les a pas notés, il faudra donc soit me faire confiance, soit faire un microbench

    2. Oui et c'est pour cela qu'il est "bête", parce qu'il va regarder toutes les annotations de jointure placés sur les Entities, et créer des jointures même quand cela n'est pas nécessaire. Si je fais du SQL (on évoque les requêtes natives je suppose) autant ne pas faire de JPA.

    3. Toutes les "conversations" (blocs de requêtes INSERT/UPDATE/DELETE je suppose) ne sont pas transactionnelles. Est implicitement transactionnelle si on utilise le mode JTA, mais si on travaille en RESOURCE_LOCAL (en Java SE par exemple) il faudra soi-même gérer les transactions. Enfin il n'y a pas de "transaction fille" avec JPA, ce dernier ne gère pas les transactions imbriquées car toutes les bases SQL ne gèrent pas cela (ex: PostgreSQL).

    4. Tu prends n'importe quelle requête nécessitant une sous-requête avec un LIMIT 1, tu n'y arriveras pas en JPQL, et ce n'est qu'un exemple. JPA propose le minimum syndical de ce que propose le SQL des SGBDR afin d'assurer l’interopérabilité... adieu les fonctions magiques TO_CHAR, TO_DATE
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  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 Gugelhupf Voir le message
    1. Un ami et moi avons créé un batch en utilisant JPA/Hibernate, et reproduit l'équivalent avec JDBC. JDBC est plus rapide, déjà le temps de l'initialisation de ce dernier est négligeable par rapport à JPA/Hibernate. Pour les chiffres on ne les a pas notés, il faudra donc soit me faire confiance, soit faire un microbench
    J'ai également écrit un gros batch de déchargement et je passe plus de 90% de mon temps sur le serveur SGBD ...

    Citation Envoyé par Gugelhupf Voir le message
    2. Oui et c'est pour cela qu'il est "bête", parce qu'il va regarder toutes les annotations de jointure que tu as placés dans les Entities, et créer des jointures même quand cela n'est pas nécessaire. Si je lui met du SQL (on évoque les requêtes natives je suppose), autant ne pas faire de JPA.
    Si tes "jointures" ne sont pas en "auto fetch", il ne fera aucune jointure. Quand au SQL natif, ca me permet de contrôler finement ce que je fais mais je le fais à mes dépends.
    Et JPA m'offre des facilités pour jongler avec le SQL et le Java. Donc non, l'utilisation d'un peu de natif (ou de custo) n'est pas un critère (ou une justification) suffisant pour se passer de JPA. Mais je ne dis pas que ca ne doit pas être pris en compte.
    Le vrai critère est : est-ce pire avec ou sans ?

    Citation Envoyé par Gugelhupf Voir le message
    3. Toutes les "conversations" (blocs de requêtes INSERT/UPDATE/DELETE je suppose) ne sont pas transactionnelles. Est implicitement transactionnelle si on utilise le mode JTA, mais si on travaille en RESOURCE_LOCAL (en Java SE par exemple) il faudra soi-même gérer les transactions. Enfin il n'y a pas de "transaction fille" avec JPA, ce dernier ne gère pas les transactions imbriquées car toutes les bases SQL ne gèrent pas cela (ex: PostgreSQL).
    Je n'utilise qu'Hibernate, le standard étant bcp trop standard pour mes besoins. Mais JPA ayant été construit par dessus Hibernate, je suppose que de nombreux éléments ont été préservés. Dès lors que tu ouvres une session, tu ouvres une connexion et une transaction.

    Citation Envoyé par Gugelhupf Voir le message
    4. Tu prends n'importe quelle requête nécessitant une sous-requête avec un LIMIT 1, tu n'y arriveras pas en JPQL, et ce n'est qu'un exemple. JPA propose le minimum syndical de ce que propose le SQL des SGBDR afin d'assurer l’interopérabilité... adieu les fonctions magiques TO_CHAR, TO_DATE
    Idem que précédemment, en HQL tout ce qu'il ne le connait pas il a tendance à le prendre pour du SQL et le conserve dans la requête générée. Donc soit tu écris une application parfaitement portable entre différents SGBD et le problème est autant dans SQL que HQL. Soit tu créées du spécifique et le problème est autant dans SQL que HQL ...
    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
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Il ne faut pas mettre au même niveau la transaction et l'ORM, ce sont 2 choses différentes...
    On parle uniquement de l'aspect "vue sous forme objet" d'une (ou plusieurs) table(s) relationnelles.

    De mon point de vue, l'ORM à surtout le gros défaut d'être utilisé n'importe comment dans la plupart des cas.
    Quand on voit le nombre de sous-entités générées automatiquement (parce qu'on a une contrainte d'intégrité référentielle), ça frôle le délire.
    Pour un peu, en accédant à une entité, on pourrait être amené à charger un graphe complet d'objets de la base de données...
    Alors oui, ils ont rajouté le lazy loading pour éviter ça, mais en pratique, on ne sait plus comment paramétrer les requêtes pour les optimiser (et c'est même impossible lorsqu'on mixe du EAGER avec du [left] join fetch).

    L'expérience me fait dire qu'il faudrait gérer les entités et leur relations entre elles juste d'un point de vue "Métier" et non pas d'un point de vue "Vue". En d'autre terme, si une facture à n lignes, alors oui, on peut créer un Set de lignes et persister le tout via la facture parce que le tout dépend de la facture. A contrario, il est (plutôt) mal venu de mapper l'article de la ligne juste parce qu'on en a besoin dans la vue. L'article a sa vie propre et ne dépend pas de la ligne. Lié à l'article, dans certains cas, on aura besoin de connaître le stock et la cascade commence

    Je vais certainement en faire bondir certains mais pour moi, le pattern DTO est bien plus efficace que le tout ORM.
    Et là, on peut mettre n'importe quoi derrière, de l'ORM ou du SQL natif... ou les 2 pourquoi pas...

    Par avance, toutes mes excuses aux dogmatiques et gourou de l'ORM, je l'utilise, mais il ne faut pas non plus prétendre que c'est la panacée
    Et si l'argument est "on n'a pas besoin de connaître SQL" alors qu'on manipule des tables de base de données relationnelles, le mieux serait peut-être de changer de métier
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    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 OButterlin Voir le message
    Il ne faut pas mettre au même niveau la transaction et l'ORM, ce sont 2 choses différentes...
    On parle uniquement de l'aspect "vue sous forme objet" d'une (ou plusieurs) table(s) relationnelles.
    Oui et non, l'ORM inter-opère avec la transaction et (Hibernate en tout cas) maintient une cohérence des objets manipulés au sein de la transaction. Par exemple si je demande 4 fois le même objet, il me renverra 4 fois la même instance. Idem il stocke également les requêtes tant que possible. De sorte qu'à la fin de la transaction, il doit être capable de lancer l'exécution des requêtes en attente.

    Citation Envoyé par OButterlin Voir le message
    De mon point de vue, l'ORM à surtout le gros défaut d'être utilisé n'importe comment dans la plupart des cas.
    Quand on voit le nombre de sous-entités générées automatiquement (parce qu'on a une contrainte d'intégrité référentielle), ça frôle le délire.
    Pour un peu, en accédant à une entité, on pourrait être amené à charger un graphe complet d'objets de la base de données...
    Alors oui, ils ont rajouté le lazy loading pour éviter ça, mais en pratique, on ne sait plus comment paramétrer les requêtes pour les optimiser (et c'est même impossible lorsqu'on mixe du EAGER avec du [left] join fetch).
    C'est pourquoi il convient de poser le comportement par défaut (ou ne jamais rien spécifier) et de bien préciser au chargement et à la sauvegarde le traitement à appliquer sur les jointures.

    Citation Envoyé par OButterlin Voir le message
    L'expérience me fait dire qu'il faudrait gérer les entités et leur relations entre elles juste d'un point de vue "Métier" et non pas d'un point de vue "Vue". En d'autre terme, si une facture à n lignes, alors oui, on peut créer un Set de lignes et persister le tout via la facture parce que le tout dépend de la facture. A contrario, il est (plutôt) mal venu de mapper l'article de la ligne juste parce qu'on en a besoin dans la vue. L'article a sa vie propre et ne dépend pas de la ligne. Lié à l'article, dans certains cas, on aura besoin de connaître le stock et la cascade commence
    Ca dépend grandement de ce que tu fais avec tes articles, tes lignes et ta facture. Par exemple, une facture présente un total. Est-ce un champ de la facture, d'une autre table ou une simple vue ? Ce sont trois solutions qui se valent et se justifient selon les besoins.

    Citation Envoyé par OButterlin Voir le message
    Je vais certainement en faire bondir certains mais pour moi, le pattern DTO est bien plus efficace que le tout ORM.
    Et là, on peut mettre n'importe quoi derrière, de l'ORM ou du SQL natif... ou les 2 pourquoi pas...
    Pour ma part, je peux trouver cela logique. Mais pour remplir ton DTO, il te faudra du "code" pour passer (mapping) du DTO (objet) au SQL (relationnel) et donc un ORM.

    Citation Envoyé par OButterlin Voir le message
    Par avance, toutes mes excuses aux dogmatiques et gourou de l'ORM, je l'utilise, mais il ne faut pas non plus prétendre que c'est la panacée
    Ce sont eux qui devraient s'excuser Les framework d'ORM sont des facilitateurs et des outils "génériques". Comme tout outil, il faut je pense surtout en connaître les limites plutôt les fonctionnalités qui tuent tout.

    Citation Envoyé par OButterlin Voir le message
    Et si l'argument est "on n'a pas besoin de connaître SQL" alors qu'on manipule des tables de base de données relationnelles, le mieux serait peut-être de changer de métier
    pour faire de l'ORM, il est important de connaître SQL. Mais je suis toujours surpris par la capacité à vivre et évoluer des projets avec un SGBD mais maintenus par des gens qui ne connaissent rien à SQL.
    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

  11. #11
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 506
    Points : 1 289
    Points
    1 289
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Et si l'argument est "on n'a pas besoin de connaître SQL" alors qu'on manipule des tables de base de données relationnelles, le mieux serait peut-être de changer de métier
    +1000

    En plus le SQL c'est simple. Si on est pas capable de comprendre SQL le reste n'ira pas.

    Et pour ce qui de l'indépendance par rapport à la DB, en 20 ans nous avons changé 3 fois d'environnement de dev, et 4 ou 5 fois de DB (DB2 VM => Oracle => DB2 Windows => DB2 AS400 => SQL Server)

    La réécriture des requêtes SQL avec la syntaxe de la nouvelle DB fût simple, par contre si toute cette logique avec été dans une syntaxe "EF" spécifique à l'environnement de dev cela aurait été beaucoup plus lourd à migrer.

  12. #12
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Logan Mauzaize Voir le message
    Oui et non, l'ORM inter-opère avec la transaction et (Hibernate en tout cas) maintient une cohérence des objets manipulés au sein de la transaction. Par exemple si je demande 4 fois le même objet, il me renverra 4 fois la même instance. Idem il stocke également les requêtes tant que possible. De sorte qu'à la fin de la transaction, il doit être capable de lancer l'exécution des requêtes en attente.
    Je ne partage pas tout à fait, il y a bien une différence entre l'ORM et la transaction, même s'il s’appuie dessus, d'ailleurs on a bien JPA et JTA.
    JPA est l'ORM


    Citation Envoyé par Logan Mauzaize Voir le message
    Ca dépend grandement de ce que tu fais avec tes articles, tes lignes et ta facture. Par exemple, une facture présente un total. Est-ce un champ de la facture, d'une autre table ou une simple vue ? Ce sont trois solutions qui se valent et se justifient selon les besoins.
    C'est un champ calculé à la création de la facture et qui ne doit plus bougé, c'est donc forcément un champ de la facture. Idem pour le libellé et tout ce qui se réfère à l'article... L'exemple est peut-être mal choisi...
    Citation Envoyé par Logan Mauzaize Voir le message
    Pour ma part, je peux trouver cela logique. Mais pour remplir ton DTO, il te faudra du "code" pour passer (mapping) du DTO (objet) au SQL (relationnel) et donc un ORM.
    Je passe par du SQL directement, pas par un ORM... je suis capable de manipuler un ResultSet pour charger mon DTO

    Citation Envoyé par Logan Mauzaize Voir le message
    Ce sont eux qui devraient s'excuser Les framework d'ORM sont des facilitateurs et des outils "génériques". Comme tout outil, il faut je pense surtout en connaître les limites plutôt les fonctionnalités qui tuent tout.
    On est bien d'accord, non à la vision dogmatique... parfois c'est bien et c'est facile à mettre en œuvre (dans les cas simples), parfois non
    Citation Envoyé par Logan Mauzaize Voir le message
    Mais je suis toujours surpris par la capacité à vivre et évoluer des projets avec un SGBD mais maintenus par des gens qui ne connaissent rien à SQL.
    Si tu leur demandes d'optimiser des requêtes lourdes, il n'y a plus personne
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par frfancha Voir le message
    Et pour ce qui de l'indépendance par rapport à la DB, en 20 ans nous avons changé 3 fois d'environnement de dev, et 4 ou 5 fois de DB (DB2 VM => Oracle => DB2 Windows => DB2 AS400 => SQL Server)

    La réécriture des requêtes SQL avec la syntaxe de la nouvelle DB fût simple, par contre si toute cette logique avec été dans une syntaxe "EF" spécifique à l'environnement de dev cela aurait été beaucoup plus lourd à migrer.
    Il y a quand même une relative indépendance avec la base de données, à structure égale, ça se passe plutôt bien.
    Le fait de pouvoir faire correspondre un type source (de la base) avec le type cible (de l'entity) permet pas mal de choses mais ça ne garantit pas l'indépendance.

    Mais je suis d'accord avec toi, SQL n'est pas compliqué... Ceci dit, ce n'est pas parce qu'on connaît SQL qu'on est capable de créer des bases de données parfaites. Quand je lis certains articles d'architectes DB, je me rends compte que c'est un métier à part entière...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 506
    Points : 1 289
    Points
    1 289
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Il y a quand même une relative indépendance avec la base de données, à structure égale, ça se passe plutôt bien.
    Oui bien sûr, c'est un des but de l'ORM, mais ce n'est pas ce que je veux dire:
    Nous sommes passé par 3 langages / environnement de DEV complètement différents et avoir utilisé l'ORM pour le langage/environnement du moment aurait entraîné une réécriture beaoup plus lourde que l'usage de SQL.

  15. #15
    Membre régulier
    Inscrit en
    Mars 2006
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 121
    Points : 110
    Points
    110
    Par défaut
    La meilleure solution étant de faire le rollback de tout et de revenir au langage assembleur tout court.

    A force de creuser dans cette question de pattern, nous deviendrons nous même anti-patterns

    N'oublier pas qu'un pattern est là pour faciliter et cadrer les dévs, c'est aussi la vocation des frameworks de dév, entre autres, les ORMs.

    Un pattern est là pour résoudre un problème, de manière correcte/standard/maintenable, tout comme un ORM. pour ce dernier le problème étant de détacher le monde OO du monde relationnel, qui est pour moi plus crucial que penser à la manière dont les trucs collaborent dans un niveau plus bas, que le niveau qui m'intéresse réellement, et qui est au final la couche fonctionnel propre au métier que je suis entrain d'implémenter.

    Aussi, c'est parfois pas la technologie X qui est anti-pattern, même l'usage et la manière d'intégrer et d'utiliser cette technologie X qui est anti-pattern.

  16. #16
    Membre confirmé Avatar de bruneltouopi
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2010
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2010
    Messages : 308
    Points : 466
    Points
    466
    Par défaut
    J'ai également utilisé une connexion jdbc direct.J'avoue que c'est assez pénible les requetes sql.
    Quand on passe sur JPA,En tant que débutant c'est assez éprouvant de voir le nombre de requêtes généré par l'ORM par les jointures EAGER.
    On ne sait pas utiliser la cache des spécifications.
    Mais lorsqu'on maitrises bien les concepts JPA on devient plus productif et le code est aisement maintenable.
    En plus on couple plusieurs Pattern comme les DTO pour des vues assez complexes.On réutilises des requêtes Natives pour faire des processus Batchs.
    Bref je ne pense pas que l'utilisation des ORM soit un réel problème.il faut juste peser le pour et le contre.Maintenance-Production-Adaptation-Simplicité
    Ce qui ne me tue pas me rend plus fort.

  17. #17
    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 OButterlin Voir le message
    Je passe par du SQL directement, pas par un ORM... je suis capable de manipuler un ResultSet pour charger mon DTO
    Si tu es très SQL, je te conseille d'essayer jooq, un super outil pour ceux qui "pensent" SQL plutôt qu'objet.
    C'est aussi un bon choix pour ceux qui utilisent un ORM plus pour faire du CRUD qu'autre chose, par contre, pour ce qui est graphes d'objets, hibernate reste le plus commode. Perso j'utilise les deux dans le même projet, avec un certain succès.

  18. #18
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par _skip Voir le message
    Si tu es très SQL, je te conseille d'essayer jooq, un super outil pour ceux qui "pensent" SQL plutôt qu'objet.
    C'est aussi un bon choix pour ceux qui utilisent un ORM plus pour faire du CRUD qu'autre chose, par contre, pour ce qui est graphes d'objets, hibernate reste le plus commode. Perso j'utilise les deux dans le même projet, avec un certain succès.
    Merci, je ne connaissais pas, j'aime bien l'approche

    Mais comme dit, j'utilise aussi Hibernate, soit directement soit au travers de JPA.
    Je trouve l'outil très sympa, ce que je déplore, c'est plutôt l'usage qu'en font certains, plus orienté "usage vue" que "modèle métier".

    Comme nous utilisons les EJB pour la couche métier, je suis un fervent utilisateur des pattern facade, DTO, DAO (via JPA).
    A chaque fois que je parle de DTO, je m'attends à lever des commentaires sur l'inutilité de cette couche mais en pratique, ça apporte plus d'indépendance aux applications par rapport au modèle physique de données et ça limite la maintenance d'ancienne application quand la base de données évolue (ajout de colonnes etc...)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  19. #19
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par santana2006 Voir le message
    La meilleure solution étant de faire le rollback de tout et de revenir au langage assembleur tout court.
    Ouiiiiii, j'adoooore l'idée
    Citation Envoyé par santana2006 Voir le message
    A force de creuser dans cette question de pattern, nous deviendrons nous même anti-patterns

    N'oublier pas qu'un pattern est là pour faciliter et cadrer les dévs, c'est aussi la vocation des frameworks de dév, entre autres, les ORMs.

    Un pattern est là pour résoudre un problème, de manière correcte/standard/maintenable, tout comme un ORM. pour ce dernier le problème étant de détacher le monde OO du monde relationnel, qui est pour moi plus crucial que penser à la manière dont les trucs collaborent dans un niveau plus bas, que le niveau qui m'intéresse réellement, et qui est au final la couche fonctionnel propre au métier que je suis entrain d'implémenter.

    Aussi, c'est parfois pas la technologie X qui est anti-pattern, même l'usage et la manière d'intégrer et d'utiliser cette technologie X qui est anti-pattern.
    C'est pas faux...
    Mais c'est parce qu'on est d'éternels perfectionnistes, on cherche l'outil parfait... comme on a échoué à faire des programmes parfait
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  20. #20
    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 OButterlin Voir le message
    Mais comme dit, j'utilise aussi Hibernate, soit directement soit au travers de JPA.
    Je trouve l'outil très sympa, ce que je déplore, c'est plutôt l'usage qu'en font certains, plus orienté "usage vue" que "modèle métier".

    Comme nous utilisons les EJB pour la couche métier, je suis un fervent utilisateur des pattern facade, DTO, DAO (via JPA).
    A chaque fois que je parle de DTO, je m'attends à lever des commentaires sur l'inutilité de cette couche mais en pratique, ça apporte plus d'indépendance aux applications par rapport au modèle physique de données et ça limite la maintenance d'ancienne application quand la base de données évolue (ajout de colonnes etc...)
    En fait tous les projets récents sur lesquels j'ai bossé utilisaient à un moment ou à un autre des DTO. Pouvoir mapper des tables BDD vers des classes java c'est bien, mais essayer de faire de ces classes des entités absolument omnipotentes dans lesquels on implémente des logiques métiers poussées, de la grosse validation, puis qu'on édite directement dans une vue grâce à du databinding, je n'y crois pas trop. C'est là généralement qu'on se prend en pleine gueule les problèmes de lazy loading, de merging d'ancienne entité dans des nouvelles sessions, de delete-orphans qui marchent pas comme on le voudrait etc.... Perso, je trouve que laisser un objet JPA/hibernate vivre plus longtemps que sa session, c'est une erreur (pourtant il y a des bouquins qui disent tout le contraire!).

    En ce sens, je trouve parfaitement raisonnable de créer des DTOs, soit de vulgaires tas de getter setter qui correspondent à la vue, aux champs à remplir par l'utilisateur, et de les populer avec une couche ORM. Cela rend la communication entre les controlleurs et les interfaces graphiques facile à lire et à comprendre, les données à disposition correspondent bien à ce qui est affiché ou édité et on se retrouve pas avec trop de logique dans les vues. C'est d'ailleurs de plus en plus un passage obligé dans le développement web avec les frameworks javascripts qui consomment et renvoient du JSON, un pojo simple, il suffit de le passer un coup dans Jackson. A contrario, faire ça avec des objets qui ont des références lazy loadées ou des éléments non sérialisables, c'est tout de suite la porte ouverte aux ennuis.

    Donc c'est clair, personne n'aime copier des données dans un DTO, c'est juste que c'est souvent indispensable sous peine de s'exposer à d'autres soucis nettement plus graves.

Discussions similaires

  1. Avast : « abandonner Windows XP est une grosse erreur »
    Par Hinault Romaric dans le forum Actualités
    Réponses: 29
    Dernier message: 30/03/2014, 13h09
  2. Message d'erreur lors d'une grosse requete
    Par tony8716 dans le forum Développement
    Réponses: 9
    Dernier message: 03/01/2008, 10h34
  3. Message d'erreur lors d'une grosse requete
    Par tony8716 dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 03/01/2008, 10h34
  4. Remplir une grosse BdD ??
    Par MagicManu dans le forum Outils
    Réponses: 2
    Dernier message: 15/06/2004, 15h01
  5. Réponses: 14
    Dernier message: 17/03/2003, 18h31

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