Parlant comme quelqu'un qui a passé pas mal de temps à travailler avec JPA (Java Persistence API, essentiellement l'API ORM normalisée pour Java / J2EE / EJB), qui comprend Hibernate, EclipseLink, Toplink, OpenJPA et d'autres, je vais partager certaines de mes observations.
- Les ORM ne sont pas rapides. Ils peuvent être adéquats et la plupart du temps adéquats, c'est bien, mais dans un environnement à faible latence et à volume élevé, ce n'est pas le cas;
- Dans les langages de programmation à usage général comme Java et C #, vous avez besoin de beaucoup de magie pour les faire fonctionner (par exemple, tissage de temps de chargement en Java, instrumentation, etc.);
- Lorsque vous utilisez un ORM, plutôt que de vous éloigner de SQL (ce qui semble être l'intention), vous serez étonné du temps que vous passerez à peaufiner XML et / ou des annotations / attributs pour que votre ORM génère du SQL performant;
- Pour les requêtes complexes, il n'y a vraiment aucun substitut. Comme dans JPA, il y a des requêtes qui ne sont tout simplement pas possibles qui sont en SQL brut et quand vous devez utiliser du SQL brut en JPA ce n'est pas joli (C # /. Net a au moins des types dynamiques - var - ce qui est beaucoup plus agréable qu’un tableau Object);
- Il y a énormément de "pièges" lors de l'utilisation des ORM. Cela inclut un comportement inattendu ou inattendu, le fait que vous devez intégrer la capacité d'effectuer des mises à jour SQL dans votre base de données (en utilisant refresh () dans JPA ou des méthodes similaires car JPA par défaut met tout en cache pour ne pas intercepter une base de données directe mise à jour - l'exécution de mises à jour SQL directes est une activité courante de support à la production);
- Le décalage objet-relationnel va toujours causer des problèmes. Avec un tel problème, il existe un compromis entre la complexité et l'exhaustivité de l'abstraction. Parfois, je sentais que JPA allait trop loin et frappait une véritable loi de rendements décroissants où la complexité n'était pas justifiée par l'abstraction.
Il y a un autre problème qui nécessite un peu plus d'explications.
Le modèle traditionnel pour une application Web est d'avoir une couche de persistance et une couche de présentation (éventuellement avec un service ou d'autres couches entre les deux mais ce sont les deux importantes pour cette discussion). Les ORM forcent une vue rigide de votre couche de persistance jusqu'à la couche de présentation (c'est-à-dire vos entités).
L'une des critiques des méthodes SQL plus brutes est que vous vous retrouvez avec tous ces VO (objets de valeur) ou DTO (objets de transfert de données) qui sont utilisés par une seule requête. Ceci est présenté comme un avantage des ORM parce que vous vous en débarrassez.
Le problème est que ces problèmes ne disparaissent pas avec les ORM, ils se déplacent simplement vers la couche de présentation. Au lieu de créer des VO / DTO pour les requêtes, vous créez des objets de présentation personnalisés, généralement un pour chaque vue. Comment est-ce mieux? À mon humble avis, ce n'est pas le cas.
J'ai écrit à ce sujet dans ORM ou SQL: en sommes-nous encore là? .
Ma technologie de persistance de choix (en Java) de nos jours est ibatis. C'est un wrapper assez mince autour de SQL qui fait 90% + de ce que JPA peut faire (il peut même faire du chargement paresseux des relations bien que ce ne soit pas bien documenté) mais avec beaucoup moins de frais généraux (en termes de complexité et de code réel).
Cela est apparu l'année dernière dans une application GWT que j'écrivais. Beaucoup de traduction d'EclipseLink vers des objets de présentation dans l'implémentation du service. Si nous utilisions ibatis, il aurait été beaucoup plus simple de créer les objets appropriés avec ibatis, puis de les passer tout le long de la pile. Certains puristes pourraient soutenir que c'est Bad ™. Peut-être que oui (en théorie) mais je vous dis quoi: cela aurait conduit à du code plus simple, une pile plus simple et plus de productivité.