147 votes

Faiblesses d'Hibernate

J'aimerais savoir quels sont les points faibles d'Hibernate 3. Il ne s'agit pas d'un fil de discussion contre Hibernate. Je pense que ce sera une connaissance très utile pour décider si Hibernate est la meilleure option pour un projet ou pour estimer son temps.

Une faiblesse peut être :

  • Un insecte
  • Quand JDBC ou PLSQL sont meilleurs
  • Problèmes de performance
  • ...

De plus, il serait utile de connaître les solutions à ces problèmes, les meilleurs ORM ou techniques, ou bien cela sera corrigé dans Hibernate 4.

Par exemple, AFAIK, Hibernate aura de très mauvaises performances pour la mise à jour de 10000 lignes par rapport à JDBC dans cette requête :

update A set state=3 where state=2

219voto

Pascal Thivent Points 295221

Hibernate est vraiment grand mais il faut absolument des compétences et de l'expérience : la connaissance des concepts ORM, des mappings et des relations est bienvenue, la compréhension de la façon dont le programme Session la compréhension de concepts plus avancés tels que le lazy-loading, les stratégies de récupération, la mise en cache (cache de premier niveau, cache de second niveau, cache de requête), etc.

Bien sûr, lorsqu'il est utilisé correctement, Hibernate est une arme redoutable : il est efficace, il génère de meilleures requêtes SQL que beaucoup (la plupart ?) de développeurs, il est très puissant, il a d'excellentes performances, etc. Cependant, j'ai vu de nombreux projets l'utiliser très mal (par exemple, ne pas utiliser les associations parce qu'ils avaient peur de "récupérer toute la base de données" et c'est loin d'être la pire des horreurs) et je suis donc toujours un peu méfiant quand j'entends "on fait du Hibernate". En fait, entre de mauvaises mains, cela peut être un vrai désastre.

Par conséquent, si je devais mentionner une faiblesse, ce serait la courbe d'apprentissage. Ne la sous-estimez pas.

49voto

Michael Wiles Points 7570

Je sors d'un grand projet utilisant Hibernate et voici les 3 faiblesses que je pense qu'Hibernate a

1. Mauvaise gestion de l'héritage des objets et aversion pour l'instrumentation

Lorsque vous chargez un objet dans Hibernate (et vous avez utilisé load pour qu'il s'agisse d'un proxy), si cet objet est en réalité (comme spécifié par la base de données) une sous-classe de celui que vous avez chargé, Hibernate ne chargera pas le type réel de l'objet. Vous l'obtiendrez en tant que proxy sur le type que vous avez demandé lorsque vous l'avez chargé (et non un proxy sur le type réel de l'objet). Donc

A a = (A) session.load("id", A.class);

Même si, dans la base de données, cet identifiant est de type B (une sous-classe de A), vous n'obtiendrez qu'un proxy de A (et non de B). Pour obtenir le vrai type, vous devez procéder à une autre étape.

La même chose se produit lorsqu'on parcourt une arborescence d'objets.

Heureusement, l'utilisation de l'instrumentation permet de résoudre le problème de l'exploration en ce sens que si un objet est instrumenté, l'exploration de l'arbre des objets permet de récupérer les types réels (sauf si l'objet est extrait d'une collection de plusieurs à plusieurs).

L'instrumentation ne résout pas l'anomalie de charge et elle existe toujours, mais l'instrumentation pourrait être utilisée pour résoudre ce problème également.

2. Sauvegarder un important nouveau modèle d'objet en une seule fois

Nous avions plusieurs processus qui généraient un grand nombre de nouveaux objets d'entité (objets persistants) et j'avais besoin de les sauvegarder. Je ne pouvais pas simplement appeler save sur l'objet source et m'attendre à ce que tout soit sauvegardé. Vous pouvez vous demander pourquoi je n'ai pas configuré la cascade pour faire cela, oui, je pourrais configurer la cascade pour l'un des cas d'utilisation, mais lorsque je lance un autre processus qui crée de nouveaux objets, cela nécessiterait sa propre structure de cascade. J'aimerais donc qu'Hibernate dispose d'une fonction permettant de sauvegarder arbitrairement un ensemble d'objets. Pour contourner ce problème, j'ai parcouru l'arbre des objets de manière réflexive en appelant la fonction de sauvegarde pour chaque objet, et j'ai dû le faire dans un ordre particulier. La fonction que je recherche ici s'appelle la persistance par accessibilité.

3. Spécifier les limites de ce que je souhaite voir préfixé, tâche par tâche

Je sais qu'avec Hibernate, il est possible de prélever une collection par le biais d'un mot-clé dans une requête, mais cela n'est souvent pas suffisant. Supposons que vous souhaitiez travailler avec un ensemble d'objets liés, vous voudriez qu'ils soient tous prérécupérés dès le départ afin d'éviter tout ralentissement et toute inefficacité par la suite. De plus, il peut y avoir plusieurs ensembles d'objets pour les différentes tâches que vous cherchez à effectuer, tous avec leur propre "profil de récupération".

Heureusement, le troisième est prévu pour la version 3.5 d'Hibernate et est connu sous le nom de "fetch profiles" (profils de récupération).

17voto

flybywire Points 36050
  1. Hibernate vous permet d'accéder aux objets JDBC sous-jacents, de sorte que si vous préférez faire certaines choses en JDBC brut, vous pouvez le faire (dans la même transaction).

  2. Hibernate prend en charge les mises à jour en masse comme dans votre exemple, et elles sont effectuées directement dans la base de données.

Si vous partez de zéro, Hibernate sera parfait pour votre projet. (Hibernate peut être un peu difficile si vous faites de l'ingénierie inverse d'une base de données existante). La philosophie est de laisser Hibernate faire tout, et seulement si vous trouvez un goulot d'étranglement et que vous trouvez qu'Hibernate fait des choses qui ne sont pas optimales, vous pouvez essayer de le modifier ou d'écrire votre requête en JDBC simple.

Je pense que pour les projets généraux, Hibernate n'a pas de faiblesses face à JDBC. Il présente en outre plusieurs avantages.

  • Votre application sera cross RDBMS.
  • Votre application sera plus sûre (Hibernate utilise des requêtes préparées en interne).
  • Dans 99 % des cas, votre application sera plus performante.

16voto

Thomas Jung Points 17692

Il y a quelques les compromis en matière de conception lorsque vous utilisez Hibernate.

Par exemple, vous ne pouvez pas être sûr qu'un objet est entièrement initialisé après l'appel de son constructeur. Hibernate impose un constructeur par défaut et initialise votre objet par des appels successifs de setter. Cela rend la vérification des invariants plus difficile car vous ne pouvez pas simplement dire qu'après l'appel du constructeur, je peux vérifier les invariants. Cela a un impact considérable sur la conception de l'objet du domaine.

14voto

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X