Comment Hibernate a presque ruiné ma carrière
Publié: 2022-03-11Imaginez que vous êtes un développeur Java et que vous êtes sur le point de démarrer votre prochain grand projet. Vous devez prendre les décisions fondamentales qui resteront avec vous pour le reste du projet. Vous souhaitez choisir la meilleure abstraction orientée objet de votre modèle de données flexible, car vous ne souhaitez pas traiter avec du SQL ordinaire. Vous souhaitez prendre en charge toutes sortes de données et, idéalement, prendre en charge toutes sortes de bases de données.
La réponse évidente est simplement d'utiliser Hibernate , n'est-ce pas ? 90 % des développeurs Java seraient d'accord avec vous, mais cela en fait-il la bonne décision ?
Jetons un coup d'œil à ce qui peut mal tourner si vous utilisez aveuglément Hibernate simplement parce que c'est la norme acceptée.
Considérez Monica, un développeur Java. Monica a récemment été promue au poste d'architecte et est maintenant responsable de la mise en place de la pile technologique d'un nouveau produit dans son entreprise. Elle sait que dans le monde Java, il n'y a qu'un seul bon outil pour gérer la communication de la base de données : Hibernate . Hibernate est une norme JPA bien connue et prise en charge. Cependant, c'est toujours une bonne idée de vérifier quelques points avant de commencer un projet. Heureusement, son collègue, Ben, connaît le bon gars.
L'hibernation ressemble à une solution miracle
Ben - Bonjour Monica, j'aimerais vous présenter John. C'est un expert d' Hibernate , et il va vous aider.
Monica - Salut John, contente que tu aies trouvé du temps pour moi. Donc, nous construisons notre Next Big Thing, vous savez. Nous envisageons de devenir le prochain Facebook ou Google. Jours occupés. Ça va être énorme. Absolument fantastique! Tout le monde est tellement excité ! J'ai été promu au poste d'architecte, je dois donc maintenant sélectionner la pile que nous allons utiliser. La seule partie manquante est la persévérance…
John - Hibernez !
Monique - Oui ! Exactement! Juste ce que je pensais ! Cela semble être un match parfait et la vraie affaire pour nous. Une véritable solution d'entreprise pour un véritable problème d'entreprise, éprouvée par le marché et avec une longue histoire. J'ai entendu tellement d'expériences positives avec elle. Cependant, j'ai un problème avec l'un de nos coéquipiers; il est totalement contre. Il en sait beaucoup sur les bases de données et il a peur d'ajouter une autre couche entre notre application et la base de données. Il est super intelligent, et j'ai besoin de très bons arguments pour le convaincre que c'est une bonne décision. Pouvez-vous m'aider?
Jean - Bien sûr ! Je serai ravi de. Hibernate est, en effet, un outil exceptionnel. Il est largement utilisé dans les grandes et véritables solutions d'entreprise, comme les banques. Vous ne pouvez pas vous tromper. Pensez à la persistance : choisissez Hibernate . Si vous écrivez en Java, c'est absolument le bon choix, en plus vous avez des ports pour d'autres langages. Voyez combien de descriptions de poste l'exigent!
Monique - Je suis absolument d'accord ! J'ai les mêmes sentiments à ce sujet. Dans un projet précédent, nous utilisions principalement SQL via JDBC. Ridicule! Je sais! Mais voici le problème : nous avons des gars SQL vraiment intelligents dans l'équipe et quand ils ont vu SQL généré par Hibernate , ils sont devenus nerveux. Cela semblait laid et illisible; cela posera-t-il un problème à l'avenir ?
Jean - Regarde. Les gars DBA ont une perspective différente. Ils ont peur d' Hibernate car cela semble remplacer leur rôle dans le projet. De plus, les bases de données ont des optimiseurs de requêtes intégrés, vous n'avez donc pas à vous soucier de l'apparence réelle de ces requêtes. La base de données l'optimisera pour vous. Il s'agit d'un développement rapide, ce que SQL ne peut pas faire.
Monique - Vraiment ?! Vous ne traitez plus avec SQL ? Étonnante! La dernière fois, un DBA a passé des semaines à essayer d'optimiser certaines requêtes. Semaines! Oh, je me sens tellement gêné de vous dire cela, mais saviez-vous que nous utilisions … des procédures stockées (rires). Oh, c'était un tel gâchis. Pouvez-vous croire que le projet l'utilise encore ? Je suis tellement désolé pour les gens là-bas. Ils doivent encore écrire ce code fastidieux encore et encore. Je me demande si c'est toujours un projet Java ou SQL ?
John - C'est exactement la différence entre une approche orientée objet et une approche relationnelle. C'est ce qu'on appelle une inadéquation d'impédance orientée objet. Hibernate peut combler cet écart. Les développeurs peuvent se concentrer sur la construction de la logique métier. Les fonctionnalités push rendent les parties prenantes et l'ensemble de la direction heureuses. Faites les choses qui comptent le plus : Business ! Beaucoup de code passe-partout disparaîtra et vous aurez une connexion magique, invisible, mais fiable, entre la logique et les données.
Monica - Coopération mutuelle. Pleine synergie. Comme si la base de données faisait partie du langage depuis le tout début. Je suis tellement heureux d'être un leader de cet acte de foi technologique. C'est comme la vitesse de distorsion dans le trek logiciel.
Jean - Ouais ! Vous l'avez!
Monica - Oh mon dieu, je suis tellement excitée ! Merci Jean ! Je suis prêt!
Problèmes de croissance avec des solutions non flexibles
Monica - Hey John, tu te souviens du projet dont nous avons parlé l'année dernière ?
Jean - Bien sûr. Comment ça va?
Monica - Nous allons bientôt en production. Tout va bien, mais certaines questions ont surgi.
John - Bien sûr, frappe-moi.
Monica - Eh bien, nous ne pouvons plus générer notre schéma de base de données à partir de zéro. Quelle est la meilleure façon de prendre en charge les modifications de schéma sans perdre de données ?
John - Eh bien, tout d'abord, Hibernate n'est pas destiné à être utilisé comme outil de migration de production. Utilisez quelque chose comme FlywayDB ou Liquibase. C'est assez simple. Vous écrivez des scripts de migration, puis vous mettez à jour le modèle d'entité avec les mappages Hibernate , afin qu'il reste synchronisé avec la structure réelle de la base de données.
Monica - Hum, je vois. Nous utilisions simplement la migration SQL dans le projet précédent.
John - C'est bien aussi. Tant que vous maintenez le modèle d'entité et le schéma synchronisés, faites-le comme vous le souhaitez.
Monique - Je vois. Il y a autre chose. Nous sommes toujours aux prises avec des problèmes de récupération paresseux/empressés. À un moment donné, on a décidé de tout faire avec empressement, mais cela semble sous-optimal, et en plus, il n'est parfois pas possible d'accéder à certains champs parce qu'il n'y a pas de session, ou quelque chose comme ça. Est-ce normal?
John - Vous devez en savoir plus sur Hibernate . La cartographie à partir de la base de données n'est pas simple. Fondamentalement, il existe plusieurs façons de le faire. Il vous suffit de choisir une méthode qui vous convient. La récupération différée vous donne la possibilité de charger ces objets à la demande, mais vous devez opérer dans une session active.
Monica - Nous nous débattons toujours avec le moteur de base de données à utiliser pour le déploiement final. Je pensais qu'Hibernate était portable, mais nous avons des requêtes natives qui utilisent de la magie MS SQL, et nous aimerions en fait utiliser MySQL dans la production.
John - Hibernate vous donne de la flexibilité tant que vous utilisez des critères détachés ou HQL ; toute requête native liera simplement votre solution à la base de données.
Monica - On dirait que nous devons nous en tenir au MS SQL alors. Dernière question : Mon coéquipier a dit qu'il n'y avait pas de mot-clé "limite" dans HQL. Je pensais qu'il plaisantait, mais je ne pouvais pas le trouver non plus. Désolé pour la question stupide…
John - En effet, il n'y a pas de mot-clé "limite" dans HQL. Vous pouvez contrôler cela via un objet de requête car il est spécifique au fournisseur de base de données.
Monica - Cela semble bizarre que tous les autres éléments soient en HQL. Ça ne fait rien. Merci pour votre temps!
Nous piratons à nouveau ensemble des solutions en SQL
Monica - John, au début, nous n'allions pas nous occuper de SQL, mais maintenant il semble que nous devions le faire. Nos besoins augmentent et il semble qu'il n'y ait pas moyen de contourner cela. Cela ne semble pas correct, mais nous avons recommencé à utiliser SQL quotidiennement.

John - Eh bien, ce n'est pas faux. Vous n'aviez pas à vous concentrer sur la base de données au tout début. Cependant, à mesure que le projet grandit, il est bon d'utiliser SQL et de travailler sur l'optimisation des performances.
Monica - Parfois, nous passons des jours à chercher des erreurs. Il semble que nous devions analyser le SQL généré par Hibernate car nous ne savons pas pourquoi il ne fonctionne pas comme prévu et produit des résultats inattendus. Nous avons rencontré des problèmes bien connus dans le gestionnaire de bogues d' Hibernate . De plus, il est difficile d'écrire des migrations appropriées tout en gardant le modèle d'entité synchronisé. Cela prend du temps car nous devons en apprendre beaucoup sur les composants internes d' Hibernate et prédire comment cela fonctionnera.
John - Il y a toujours une courbe d'apprentissage. Vous n'avez pas besoin d'écrire beaucoup, mais vous devez savoir comment cela fonctionne.
Monica - Travailler avec des ensembles de données plus volumineux est également ennuyeux. Récemment, nous avons effectué une importation massive dans la base de données, et c'était extrêmement lent. Ensuite, nous avons découvert que nous devions effacer la session pour la rendre plus rapide. Même ainsi, il est encore beaucoup plus lent, nous avons donc décidé de le réécrire sous forme d'instructions SQL simples. Ce qui est drôle, c'est qu'écrire du SQL brut était en fait le moyen le plus rapide de le faire, nous avons donc décidé de le faire comme dernière option.
John - L'importation n'est pas un processus orienté objet. Hibernate se concentre sur la conception orientée objet. N'oubliez pas que vous pouvez toujours utiliser des requêtes natives.
Monica - Pouvez-vous m'aider à comprendre comment fonctionne le cache Hibernate ? Je ne comprends tout simplement pas. Il existe des caches de premier/deuxième niveau. Qu'est-ce que tout cela?
Jean - Bien sûr. Il s'agit d'un soi-disant cache de niveau transactionnel de données persistantes. Il est possible de configurer un cluster ou un cache de niveau JVM classe par classe et collection par collection. Vous pouvez même brancher un cache en cluster. Mais rappelez-vous que les caches ne sont pas au courant des modifications apportées au magasin persistant par une autre application. Ils peuvent cependant être configurés pour supprimer régulièrement les données en cache expirées.
Monica - Désolé, je pense que je passe une mauvaise journée. Pouvez-vous expliquer cela un peu plus?
Jean - Bien sûr. Chaque fois que vous passez un objet à save
, update
, saveOrUpdate
ou le récupérez via load
, get
, list
, iterate
ou scroll
, cet objet est ajouté au cache interne de la session. Vous pouvez également supprimer l'objet et ses collections du cache de premier niveau.
Monica - Euh…
John - De plus, vous pouvez contrôler les modes de cache. Vous pouvez utiliser le mode normal
pour lire et écrire des éléments dans le cache de second niveau. Utilisez le mode get
pour lire à partir du deuxième niveau, mais vous ne pouvez pas réécrire. Utilisez put
, qui est identique à get
mais vous ne pouvez pas lire à partir du deuxième niveau. Vous pouvez également utiliser le mode d' refresh
, qui va écrire au deuxième niveau, mais pas en lire et contourner la propriété use minimal puts
, forçant une actualisation du cache de deuxième niveau pour tous les éléments lus à partir de la base de données.
Monique - Je vois. D'accord. Laissez-moi réfléchir à ça. Oh, il est tard, je dois y aller. Merci pour votre temps!
Jean - De rien !
Abandonner l'hibernation
Monica - John, je pensais que nous entrions dans une nouvelle ère de développement logiciel. Je pensais que nous faisions un saut d'une année-lumière. Mais, après quatre ans, il semble que nous soyons toujours confrontés aux mêmes problèmes, mais sous un angle différent. J'ai dû apprendre l'architecture Hibernate , la configuration, la journalisation, les stratégies de nommage, les tuplizers, les résolveurs de noms d'entités, les générateurs d'identifiants améliorés, l'optimisation des générateurs d'identifiants, les sous-classes d'union, le balisage XDoclet, les associations bidirectionnelles avec des collections indexées, les associations ternaires, l'idbag, le mélange de polymorphisme implicite avec autres mappages d'héritage, réplication d'objets entre deux magasins de données différents, objets détachés et gestion automatique des versions, modes de libération de connexion, interface de session sans état, taxonomie de la persistance de la collection, niveaux de cache, récupération paresseuse ou impatiente et bien d'autres encore. Même avec tout ce que je sais, il semble que nous ayons échoué. C'est un fiasco logiciel ! Échec ultime ! Catastrophe! Armageddon!
Jean - Attends ! Qu'est-il arrivé?
Monica - Nous sommes dans une impasse. Les performances de nos applications sont ridiculement lentes ! Pour obtenir un rapport, nous devons attendre deux jours ! Deux jours pour réellement générer un tableau de bord pour un client. Cela signifie que chaque jour nous devons augmenter notre queue de calcul, alors que notre tableau de bord devient de plus en plus obsolète. Notre expert DBA a travaillé deux mois pour optimiser certaines requêtes, alors que la structure de notre base de données est en désordre. Il y a des développeurs qui le soutiennent, mais le problème est que le DBA pense en SQL, et les développeurs passent des jours à essayer de traduire cela en critères détachés ou en format HQL. Nous essayons d'utiliser au maximum le SQL natif car les performances sont cruciales pour le moment. Quoi qu'il en soit, nous ne pouvons pas faire grand-chose car le schéma de la base de données semble simplement erroné. Cela semblait juste du point de vue orienté objet, mais cela semble ridicule du point de vue relationnel. Je me demande : Comment est-ce arrivé ? Les développeurs nous disent que changer la structure des entités va être un énorme effort, donc nous ne pouvons pas nous le permettre. Je me souviens que dans le projet précédent, c'était un gâchis, mais nous ne nous sommes jamais retrouvés à un point aussi critique. Nous avons pu écrire une application entièrement différente pour travailler avec les données. Maintenant, il est risqué de modifier ces tables générées car il est vraiment difficile de s'assurer que le modèle d'entité se comportera toujours correctement. Et ce n'est même pas le pire ! Pour augmenter les performances, nous devons résoudre non seulement les problèmes de base de données, mais également les problèmes de toute la couche entre notre base de données et l'application. C'est écrasant ! Nous avons ces nouveaux gars, vous savez, des consultants. Ils essaient d'extraire des données, de les placer dans un autre stockage, puis d'effectuer des calculs de l'extérieur. Tout cela prend trop de temps !
John - Je ne sais pas quoi dire.
Monica - Vous voyez John; Je ne veux pas te blâmer. J'ai choisi Hibernate pour résoudre tous ces problèmes, mais maintenant j'ai appris que ce n'est pas une solution miracle. Le mal est fait et il est irréversible. En fait, je voudrais vous demander quelque chose : j'ai passé les quatre dernières années de ma carrière à m'occuper de trucs Hibernate . Il semble que je n'ai pas d'avenir dans mon entreprise actuelle. Pouvez-vous m'aider?
Alors, quelle est la leçon apprise ?
John - Hé, Peter, laisse-moi te présenter Monica.
Pierre - Salut, Monique ! Nous construisons notre nouvelle prochaine grande chose, vous savez. Ça va être énorme ! Nous voulons être comme Uber ! Savez-vous peut-être à quel point la persévérance…
Monica - Pas d'hibernation !
Emballer
Monica est une experte de l' hibernation . Cependant, Hibernate dans ce cas était une mauvaise décision. Au moment où elle a découvert que sa solution s'était transformée en un problème plus important que l'original, c'était la plus grande menace pour l'ensemble du projet.
Les données sont l'objectif central de l'application et, qu'on le veuille ou non, affectent l'ensemble de l'architecture. Comme nous l'avons appris de l'histoire, n'utilisez pas Hibernate simplement parce que votre application Java utilise une base de données ou à cause de la preuve sociale. Choisissez une solution qui embrasse la flexibilité. Il existe de nombreuses options pour les wrappers JDBC robustes, tels que JdbcTemplate ou Fluent JDBC Wrapper. Alternativement, il existe d'autres solutions puissantes, telles que jOOQ.