67 votes

Hibernate, iBatis, Java EE ou autre outil ORM Java

Nous sommes en train de planifier une grande application d'entreprise. Nous concentrons nos efforts sur l'évaluation d'Hibernate après avoir fait l'expérience des difficultés de J2EE.

Il semble que la nouvelle API Java EE soit plus simple. J'ai également lu de bonnes choses sur Hibernate et iBatis. Notre équipe a peu d'expérience avec l'un de ces frameworks.

Il y a 5 points de comparaison principaux que j'aimerais déterminer

  • Courbe d'apprentissage/Facilité d'utilisation
  • Productivité
  • Maintenabilité/Stabilité
  • Performance/Scalabilité
  • Facilité de dépannage

Si vous deviez gérer une équipe de ~6 développeurs ayant une expérience J2EE, quel outil ORM utiliseriez-vous et pourquoi ?

112voto

cletus Points 276888

Laissez-moi essayer. Tout d'abord, j'ai déjà écrit sur ce sujet en Utiliser un ORM ou du SQL pur ? . Pour répondre spécifiquement à vos points :

Courbe d'apprentissage/Facilité d'utilisation

Ibatis concerne le SQL. Si vous connaissez SQL, la courbe d'apprentissage d'ibatis est triviale. Ibatis fait certaines choses au dessus de SQL comme :

  • groupe par ;
  • les types discriminés ; et
  • SQL dynamique.

que vous devrez apprendre, mais le plus gros obstacle est SQL.

JPA (qui comprend Hibernate), quant à lui, tente de prendre ses distances par rapport à SQL et de présenter les choses sous forme d'objets plutôt que sous forme relationnelle. Comme Joel le souligne cependant, les abstractions sont peu fiables et JPA ne fait pas exception. Pour utiliser JPA, vous devrez toujours connaître les modèles relationnels, le langage SQL, l'optimisation des performances des requêtes, etc.

Alors qu'Ibatis vous demandera simplement d'appliquer le SQL que vous connaissez ou que vous êtes en train d'apprendre, JPA vous demandera de savoir autre chose : comment le configurer (soit en XML, soit en annotations). J'entends par là qu'il faut comprendre que les relations de type clé étrangère sont des relations (une à une, une à plusieurs ou plusieurs à plusieurs) d'un certain type, le mappage des types, etc.

Si vous connaissez SQL, je dirais que la barrière à l'apprentissage de JPA est en fait plus élevée. Si ce n'est pas le cas, le résultat est plus mitigé, JPA vous permettant effectivement de différer l'apprentissage de SQL pendant un certain temps (mais pas de le reporter indéfiniment).

Avec JPA, une fois que vous avez configuré vos entités et leurs relations, les autres développeurs peuvent simplement les utiliser et n'ont pas besoin d'apprendre tout ce qui concerne la configuration de JPA. Cela peut être un avantage, mais un développeur devra toujours connaître les gestionnaires d'entités, la gestion des transactions, les objets gérés et non gérés, etc.

Il convient de noter que JPA possède également son propre langage de requête (JPA-SQL), que vous devrez apprendre, que vous connaissiez ou non le langage SQL. Vous trouverez des situations où JPA-SQL ne peut tout simplement pas faire des choses que SQL peut faire.

Productivité

C'est une question difficile à juger. Personnellement, je pense que je suis plus productif avec ibatis, mais je suis aussi très à l'aise avec SQL. Certains diront qu'ils sont beaucoup plus productifs avec Hibernate, mais c'est peut-être dû, du moins en partie, à leur méconnaissance de SQL.

La productivité de JPA est également trompeuse, car vous rencontrerez parfois un problème avec votre modèle de données ou vos requêtes qui vous prendra une demi-journée, voire une journée, pour le résoudre. Vous devrez alors ouvrir un journal et observer le SQL produit par votre fournisseur JPA, puis trouver la combinaison de paramètres et d'appels qui lui permettra de produire quelque chose de correct et de performant.

Vous n'avez pas ce genre de problème avec Ibatis parce que vous avez écrit le SQL vous-même. Vous le testez en exécutant le SQL dans PL/SQL Developer, SQL Server Management Studio, Navicat for MySQL ou autre. Une fois que la requête est correcte, tout ce que vous faites est de mettre en correspondance les entrées et les sorties.

J'ai également trouvé que JPA-QL était plus maladroit que le SQL pur. Il faut des outils distincts pour exécuter une requête JPA-QL et voir les résultats, et c'est quelque chose de plus à apprendre. En fait, j'ai trouvé toute cette partie de JPA plutôt maladroite et peu maniable, même si certaines personnes l'adorent.

Maintenabilité/Stabilité

Le danger d'Ibatis est la prolifération, ce qui signifie que votre équipe de développement peut continuer à ajouter des objets de valeur et des requêtes au fur et à mesure de ses besoins plutôt que de chercher à les réutiliser, alors que JPA a une entité par table et une fois que vous avez cette entité, c'est tout. Les requêtes nommées ont tendance à aller sur cette entité et sont donc difficiles à manquer. Les requêtes ad hoc peuvent toujours être répétées mais je pense que c'est un problème potentiel moins important.

Cela se fait toutefois au prix d'une certaine rigidité. Souvent, dans une application, vous aurez besoin de morceaux de données provenant de différentes tables. Avec SQL, c'est facile, car vous pouvez écrire une seule requête (ou un petit nombre de requêtes) pour obtenir toutes ces données en une seule fois et les placer dans un objet de valeur personnalisé spécialement conçu à cet effet.

Avec JPA, vous déplacez cette logique dans votre couche métier. Les entités sont fondamentalement tout ou rien. Ce n'est pas tout à fait vrai. Divers fournisseurs JPA vous permettront de charger partiellement des entités, etc., mais même dans ce cas, il s'agit des mêmes entités distinctes. Si vous avez besoin de données provenant de quatre tables, vous avez besoin de quatre entités ou vous devez combiner les données que vous voulez dans une sorte d'objet de valeur personnalisé dans la couche métier ou de présentation.

Une autre chose que j'aime dans ibatis est que tout votre SQL est externe (dans des fichiers XML). Certains diront que c'est un inconvénient, mais pas moi. Vous pouvez alors trouver les utilisations d'une table et/ou d'une colonne relativement facilement en cherchant dans vos fichiers XML. Avec le SQL intégré dans le code (ou lorsqu'il n'y a pas de SQL du tout), il peut être beaucoup plus difficile de le trouver. Vous pouvez également copier et coller du SQL dans un outil de base de données et l'exécuter. Je ne saurais trop insister sur le nombre de fois où cela m'a été utile au fil des ans.

Performance/Scalabilité

Ici, je pense qu'ibatis l'emporte haut la main. C'est un SQL direct et peu coûteux. De par sa nature, JPA ne sera tout simplement pas en mesure de gérer le même niveau de latence ou de débit. Ce que JPA a de bien, c'est que la latence et le débit ne sont que rarement des problèmes. Il existe cependant des systèmes à haute performance qui auront tendance à défavoriser les solutions plus lourdes comme JPA.

De plus, avec ibatis, vous pouvez écrire une requête qui renvoie exactement les données que vous voulez avec les colonnes exactes dont vous avez besoin. Fondamentalement, il n'y a aucun moyen pour JPA de battre (ou même d'égaler) cela quand il s'agit de retourner des entités discrètes.

Facilité de dépannage

Je pense que celle-ci est une victoire pour Ibatis aussi. Comme je l'ai mentionné plus haut, avec JPA, vous passerez parfois une demi-journée à faire en sorte qu'une requête ou une entité produise le SQL que vous voulez ou à diagnostiquer un problème où une transaction échoue parce que le gestionnaire d'entités a essayé de persister un objet non géré (qui pourrait faire partie d'un travail par lot où vous avez engagé beaucoup de travail, donc il pourrait être non trivial à trouver).

Les deux échoueront si vous essayez d'utiliser une table ou une colonne qui n'existe pas, ce qui est une bonne chose.

Autres critères

Vous n'avez pas mentionné la portabilité comme l'une de vos exigences (c'est-à-dire le passage d'un fournisseur de base de données à un autre). Il est intéressant de noter qu'ici JPA a l'avantage. Les annotations sont moins portables que, par exemple, le XML d'Hibernate (par exemple, les annotations JPA standard n'ont pas d'équivalent pour le type d'ID "natif" d'Hibernate) mais les deux sont plus portables qu'ibatis / SQL.

J'ai également vu JPA / Hibernate utilisé comme une forme de DDL portable, ce qui signifie que vous exécutez un petit programme Java qui crée le schéma de la base de données à partir de la configuration JPA. Avec ibatis, vous aurez besoin d'un script pour chaque base de données supportée.

L'inconvénient de la portabilité est que JPA est, d'une certaine manière, le plus petit dénominateur commun, ce qui signifie que le comportement pris en charge est en grande partie le comportement commun pris en charge par un large éventail de fournisseurs de bases de données. Si vous voulez utiliser Oracle Analytics dans ibatis, pas de problème. Dans JPA ? Eh bien, c'est un problème.

0 votes

Je pense que cela exagère vraiment l'unicité de la simplicité d'iBATIS et minimise la valeur de la logique commerciale dans la couche Java. Les requêtes natives peuvent être chargées à partir d'un fichier texte dans JPA et/ou manipulées comme des chaînes de caractères - c'est essentiellement cela, iBATIS. Dans ce sens, je considère que JPA est presque un superset. Vous pouvez utiliser des requêtes natives et les faire correspondre à des entités spécifiquement conçues, ou migrer vers JPAQL et vous essayer à la consolidation de la logique métier.

0 votes

Peut-être qu'Oracle Analytics s'intègre mieux à iBATIS (je ne sais pas ?), mais JPA est pris en charge par la plupart des conteneurs/serveurs Java, donc je dirais qu'il est plus "standard", et non l'inverse. Il est donc léger dans le sens où il s'agit au moins d'une dépendance largement disponible.

0 votes

@jm0 Je considère que c'est un inconvénient de JPA, puisque vous pouvez facilement rencontrer des conflits de version, lorsque le serveur d'applications fournit ces bibliothèques.

11voto

StaxMan Points 34626

Une règle empirique simpliste entre iBatis et Hibernate est que si vous souhaitez une vision plus SQL/relationnelle du monde, iBatis est plus adapté ; et pour une chaîne d'héritage plus complexe, et une vue moins directe sur le SQL, Hibernate. Les deux sont largement utilisés et constituent de bons cadres solides. Je pense donc que les deux fonctionneraient probablement bien. Lisez peut-être un tutoriel pour les deux, voyez si l'un semble meilleur que l'autre, et choisissez-en un.

Parmi les choses que vous citez, je ne pense pas que les performances soient très différentes - le goulot d'étranglement sera presque invariablement la base de données, pas le framework. Pour d'autres choses, je pense que différents développeurs préfèrent l'un ou l'autre, c'est-à-dire qu'il n'y a pas de priorité communément acceptée (pour iBatis vs Hibernate).

7voto

eqbridges Points 2143

La solution que vous choisirez dépendra également de votre choix (ou de votre obligation) de vous conformer à la spécification Java EE. JPA est "la norme" pour l'accès aux données dans les systèmes Java EE, donc si vous tenez à respecter cette norme, vous devriez l'utiliser (avec quelques réserves).

JPA est une normalisation des systèmes de mappage objet-relationnel. En tant que tel, il ne fournit pas d'implémentation, il définit simplement une approche standardisée. Hibernate Entity Manager est l'une de ces implémentations.

Étant donné que JPA est un standard utilisé par de nombreux fournisseurs et qu'il est encore assez récent, il lui manque certaines fonctionnalités plus ésotériques qui sont précieuses dans certains cas d'utilisation (par exemple, une API de critères pour générer du SQL dynamique). Si vous optez pour JPA, prévoyez des situations où vous devrez utiliser Hibernate directement, voire JDBC directement. Pour de telles situations, un pattern DAO générique est très utile ; vous pouvez modifier celui-ci : Objets génériques d'accès aux données pour une utilisation dans JPA & JDBC assez facilement.

JPA présente certaines restrictions difficiles (en particulier si vous êtes habitué à Hibernate), et vous impose certaines approches qui sont difficiles pour les développeurs qui sont plus habitués à écrire directement en JDBC. Si vous défendez cette approche, assurez-vous de bien connaître les avantages et les inconvénients de l'ORM par rapport à JDBC.

Si vous optez pour JPA, une fois que vous aurez atteint la courbe d'apprentissage, vous serez récompensé en termes de développement simple (en particulier si vous implémentez correctement le modèle DAO mentionné ci-dessus), mais aussi en obtenant une mise en cache à plusieurs niveaux des résultats des requêtes. Si cela est fait correctement (un grand "si", je sais), j'ai vu cela fournir des avantages considérables.

Enfin, si vous disposez d'un modèle de données patrimonial avec lequel vous avez peu de flexibilité, Hibernate (et JPA) vous donnera plus de maux de tête qu'il n'en vaut la peine. Par exemple :

  • Si la base de données ne dispose pas de clés primaires candidates (pour les implémentations efficaces de hashCode et equals), vous devrez procéder à une analyse préalable pour déterminer quelles colonnes définissent une ligne de manière unique - ce qui peut être simple ou complexe selon la complexité de votre schéma ;
  • Si vous n'êtes pas en mesure d'ajouter des colonnes de version ou d'horodatage, vous perdez la capacité d'Hibernate à effectuer un verrouillage optimiste, et vous finissez par devoir interroger avant de mettre à jour.

(Ajouté en réponse au premier commentaire) Si vous avez la chance de pouvoir redessiner votre base de données, deux très importantes considérations si vous allez utiliser un ORM :

  • Ajout d'une colonne de numéro de version à toutes les tables pertinentes pour prendre en charge le verrouillage optimiste.
  • Lors de l'analyse de vos données, choisissez des " touche alternative "colonne(s) que les développeurs doivent utiliser pour hashCode() & equals() . N'utilisez pas de colonnes PK dans ces méthodes.

0 votes

Merci, ce sont de bons points. Nous sommes en train de reconstruire l'application et le modèle de données, de sorte qu'il s'agit d'un projet entièrement nouveau, influencé par le modèle de données précédent et les capacités de l'ancien système. J'espère pouvoir choisir un outil ORM maintenant, avant que le modèle de données ne soit trop avancé.

0 votes

J'ai ajouté quelques points ci-dessus en réponse à votre commentaire.

6voto

Rob Points 890

Pour ajouter une autre option à la liste... regardez :

Ebean ORM ( http://ebean-orm.github.io ).

Sa principale revendication serait un modèle de programmation plus simple et plus intuitif que JPA ou Hibernate. Plus précisément, il n'y a pas de session Hibernate ou de gestionnaire d'entités JPA, pas d'objets détachés/attachés (pas de fusion, de persistance, de vidage), le chargement paresseux fonctionne simplement.

... un alias beaucoup plus simple à utiliser et à comprendre.

Vous pouvez également utiliser votre propre SQL avec Ebean (pour les requêtes, les mises à jour, les procédures stockées) et l'OMI égale Ibatis en termes de facilité d'utilisation de votre propre SQL.

Si vous cherchez à utiliser l'ORM dans Java SE, je vous conseille de le consulter.

  • Licence LGPL
  • Utiliser les annotations JPA pour le mapping (@Entity, @OneToMany etc)
  • API sans session (pas de merge, persist, flush ... save() et delete() à la place)
  • Support des "objets partiels".
  • Support des grandes requêtes (par contexte de persistance du graphe d'objets)
  • Requêtes de fond
  • Bonne prise en charge du traitement par lots
  • Ajustement automatique des requêtes (via "Autofetch")

Santé, Rob.

0 votes

Merci pour la suggestion. J'y jetterai un coup d'œil.

1 votes

Quelqu'un connaît-il un projet réel basé sur Ebean ? Il semble intéressant et j'aimerais voir comment il se compare aux frameworks ORM habituels.

5voto

vsingh Points 1099

Nous travaillons actuellement sur un projet qui utilise à la fois Hibernate et ibatis. Pourquoi utiliser Hibernate ? Il prend en charge notre modèle de domaine, les relations et l'héritage. Nous avons un modèle de domaine assez complexe et hibernate le supporte très bien. Il n'est pas nécessaire de s'inquiéter de l'écriture des insertions, des mises à jour, etc. Ibatis est utilisé uniquement pour les vues. Il y a des requêtes et nous avons des objets de vue (similaires aux modèles de domaine mais pas aux modèles de domaine) qui sont mappés avec des requêtes. Ibatis renvoie les données dans l'objet de vue que vous souhaitez sans vous soucier de la lecture du jeu de résultats, que vous devez gérer dans Spring JDBC. Pourquoi faire cela au lieu d'utiliser HQl ou Spring JDBC ? Le domaine est tellement complexe et lors du rendu de la vue, nous faisons des calculs, des regroupements et des tonnes de fonctions SQL natives. Nous faisons tout cela dans la requête, utilisons des requêtes dynamiques, gérons les conditions dans ibatis et obtenons un objet propre et léger. Cela a beaucoup plus de sens si vous devez traverser plusieurs couches pour récupérer des données dans Hibernate. Donc, en fonction de votre situation, vous pouvez vouloir utiliser un seul, les deux ou peut-être aucun. Mais il est certain qu'Hibernate n'est pas quelque chose dont vous ne pouvez pas vous passer.

0 votes

C'est une utilisation intéressante @vsingh. Merci pour le partage.

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