|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 565 ![]() |
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 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 : |
|
|
20
|
|
|
#2 | ||
![]() ![]() Logan Développeur Java Inscription : août 2005 Messages : 1 695 ![]() |
Citation:
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:
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 : Forum - FAQ - Java SE 7 API - Java EE 6 API 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 |
||
|
|
00
|
|
|
#3 |
|
Membre Expert
![]() Inscription : avril 2004 Messages : 1 246 ![]() |
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. |
|
|
00
|
|
|
#4 |
![]() ![]() Logan Développeur Java Inscription : août 2005 Messages : 1 695 ![]() |
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 : Forum - FAQ - Java SE 7 API - Java EE 6 API 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 |
|
|
00
|
|
|
#5 | |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 565 ![]() |
Citation:
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 |
|
|
|
00
|
|
|
#6 | |||||
![]() ![]() Logan Développeur Java Inscription : août 2005 Messages : 1 695 ![]() |
Citation:
Citation:
Citation:
Cependant j'avoue que les applications sur lesquelles je travaille sont plutôt simples. Citation:
Citation:
__________________
Java : Forum - FAQ - Java SE 7 API - Java EE 6 API 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 |
|||||
|
|
00
|
|
|
#7 | ||
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 565 ![]() |
Citation:
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. Citation:
|
||
|
|
10
|
|
|
#8 | |||
![]() ![]() Logan Développeur Java Inscription : août 2005 Messages : 1 695 ![]() |
Citation:
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:
Citation:
__________________
Java : Forum - FAQ - Java SE 7 API - Java EE 6 API 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 |
|||
|
|
20
|
|
|
#9 | |||
|
Membre éprouvé
![]() Inscription : janvier 2011 Messages : 155 ![]() |
Citation:
Citation:
Citation:
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. |
|||
|
|
00
|
|
|
#10 |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 565 ![]() |
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. |
|
|
00
|
|
|
#11 | ||
![]() ![]() Logan Développeur Java Inscription : août 2005 Messages : 1 695 ![]() |
Citation:
Citation:
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 : Forum - FAQ - Java SE 7 API - Java EE 6 API 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 |
||
|
|
00
|
|
|
#12 | ||
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 565 ![]() |
Citation:
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:
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. |
||
|
|
00
|
|
|
#13 | ||||
![]() ![]() Logan Développeur Java Inscription : août 2005 Messages : 1 695 ![]() |
Citation:
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:
pè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:
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) ? Citation:
__________________
Java : Forum - FAQ - Java SE 7 API - Java EE 6 API 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 |
||||
|
|
00
|
|
|
#14 | ||||
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 565 ![]() |
Citation:
Citation:
Non je ne connais pas de concept similaire en mybatis. Citation:
Citation:
On a du rester modeste en infrastructure afin de ne pas exploser les prix du service. |
||||
|
|
00
|
|
|
#15 | |||
![]() ![]() Logan Développeur Java Inscription : août 2005 Messages : 1 695 ![]() |
Citation:
Citation:
Citation:
__________________
Java : Forum - FAQ - Java SE 7 API - Java EE 6 API 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 |
|||
|
|
00
|
|
|
#16 | |||
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 565 ![]() |
Citation:
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. Citation:
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é. Citation:
|
|||
|
|
00
|
Copyright © 2000-2013 - www.developpez.com