Quel ORM Java préférez-vous et pourquoi? [fermé]

262

C'est une question assez ouverte. Je vais commencer un nouveau projet et je regarde différents ORM à intégrer avec l'accès à la base de données.

Avez-vous des favoris? Y a-t-il des choses dont vous conseilleriez de rester à l'écart?

Tom Neyland
la source
Jetez un œil aux micro-orms - des enveloppes minces autour de la technologie d'accès DB de la plate-forme - comme sql2o pour Java github.com/aaberg/sql2o ou ServiceStack.OrmLite pour .NET github.com/ServiceStack/ServiceStack.OrmLite
tomaszkubacki
3
Après avoir utilisé ORM pendant plus de 5 ans, mon choix personnel est Spring JDBC sur ORM, et le deuxième meilleur est iBatis (MyBatis), je n'aime pas la mise en veille prolongée en raison de la courbe d'apprentissage, de moins de problèmes de contrôle et de performances.
Voici (également fermée) la liste des wrappers jdbc légers qui peuvent être utilisés comme alternative aux orms à part entière: stackoverflow.com/questions/7137929/…
Vadzim

Réponses:

237

J'ai cessé d'utiliser des ORM.

La raison n'est pas une grande faille dans le concept. Hibernate fonctionne bien. Au lieu de cela, j'ai constaté que les requêtes ont une faible surcharge et je peux intégrer beaucoup de logique complexe dans de grandes requêtes SQL et transférer une grande partie de mon traitement dans la base de données.

Envisagez donc d'utiliser le package JDBC.

David Crawshaw
la source
81
C'est la même histoire encore et encore avec ORM: un développement initial rapide et agréable, et un gros drain sur vos ressources plus loin dans le projet lors du suivi des bogues et des inefficacités liés à ORM. Je déteste également le fait que cela semble donner aux développeurs l'idée qu'ils n'ont jamais à écrire de requêtes optimisées spécifiques.
Eelco
7
Hé, est-ce vrai pour les grands projets de la vie réelle?
santiagobasulto
30
Je suis d'accord. J'utilise ORM depuis plus de 3 ans maintenant, et je ne peux pas dire combien de temps a été perdu (est toujours) pour résoudre les problèmes liés à la persistance. Nous n'avons aucun contrôle sur ce qui se passe "sous le capot", les configurations sont trop nombreuses pour être gérées efficacement et il y a des comportements qui peuvent rendre fou. D'un autre côté, j'ai le support des principales bases de données et je n'ai jamais à me soucier de leurs différences.
marcolopes
58
pourquoi ne pas utiliser les deux, selon la complexité de la requête / transaction? ce n'est pas comme s'ils s'excluent mutuellement.
amphibient
6
@ WillSheppard oui Will. J'utilise beaucoup Django ORM et cela fonctionne très bien. Je pense que la différence pourrait être dans la nature dynamique de python (et perl). L'utilisation d'un ORM en Java est pénible. Mais dans les langages dynamiques, cela peut être vraiment expressif. Il existe d'excellents projets pour intégrer des opérations ORM comme les DSL en Python et ils sont excellents.
santiagobasulto
97

Aucun, car avoir un ORM enlève trop de contrôle avec de petits avantages. Le gain de temps gagné est facilement emporté lorsque vous devez déboguer des anomalies résultant de l'utilisation de l'ORM. De plus, les ORM découragent les développeurs d'apprendre le SQL et le fonctionnement des bases de données relationnelles et de l'utiliser à leur avantage.

Simon
la source
4
Je suis d'accord avec cette affirmation. Combien du temps de développement total sera consommé en écrivant du code de persistance? Je pense que moins de 10 à 15%
adrian.tarau
16
Ça dépend. Bien sûr, si vous utilisez un seul type de base de données, il est facile de ne pas utiliser d'ORM. Cependant, lorsque vous devez prendre en charge d'autres types de bases de données, elles peuvent rapidement devenir moins gérables.
Jason Baker
3
"Le gain de temps gagné est facilement emporté lorsque vous devez déboguer des anomalies résultant de l'utilisation de l'ORM" Ce n'est pas vrai lorsque la courbe de compétences est un facteur décent lors du choix des technologies.
elsadek
7
Votre argument pourrait être opposé à l'utilisation de n'importe quelle bibliothèque. Les gains les plus importants des ORM sont des éléments tels que les unités de travail, le mappage d'objets, le suivi des modifications, le chargement paresseux, les migrations et les relations. C'est une chose merveilleuse de pouvoir écrire user.profile.givenName sans se soucier de la structure utilisée pour stocker les données.
Alex
1
Il pourrait être utilisé contre n'importe quelle bibliothèque, mais à des degrés divers. En général, je suis un grand partisan de l'utilisation des bibliothèques - pourquoi réinventer la roue? Cependant, dans ce cas, je pense que Hibernate est pour la plupart des utilisations un poids trop lourd et un ORM plus léger serait plus préférable. Mes expériences sont basées sur plusieurs années d'expérience de développement avec Hibernate et d'apprentissage approfondi de ses tenants et aboutissants.
simon
92

De nombreux ORM sont excellents, vous devez savoir pourquoi vous souhaitez ajouter l'abstraction au-dessus de JDBC. Je peux vous recommander http://www.jooq.org (avertissement: je suis le créateur de jOOQ, donc cette réponse est biaisée). jOOQ adopte le paradigme suivant:

  • SQL est une bonne chose. Beaucoup de choses peuvent être très bien exprimées en SQL. Il n'est pas nécessaire d'abstraction complète de SQL.
  • Le modèle de données relationnel est une bonne chose. Il s'est avéré le meilleur modèle de données au cours des 40 dernières années. Il n'y a pas besoin de bases de données XML ou de modèles de données vraiment orientés objet. Au lieu de cela, votre entreprise exécute plusieurs instances d'Oracle, MySQL, MSSQL, DB2 ou tout autre SGBDR.
  • SQL a une structure et une syntaxe. Elle ne doit pas être exprimée en utilisant la concaténation de chaînes "de bas niveau" dans JDBC - ou la concaténation de chaînes "de haut niveau" dans HQL - qui sont toutes deux susceptibles de contenir des erreurs de syntaxe.
  • La liaison variable a tendance à être très complexe lorsqu'il s'agit de requêtes majeures. C'EST quelque chose qui devrait être abstrait.
  • Les POJO sont parfaits pour écrire du code Java en manipulant des données de base de données.
  • Les POJO sont difficiles à écrire et à maintenir manuellement. La génération de code est la voie à suivre. Vous aurez des requêtes sécurisées pour la compilation, y compris la sécurité des types de données.
  • La base de données vient en premier. Bien que l'application au-dessus de votre base de données puisse changer au fil du temps, la base de données elle-même va probablement durer plus longtemps.
  • Oui, vous avez des procédures stockées et des types définis par l'utilisateur (UDT) dans votre base de données héritée. Votre outil de base de données devrait supporter cela.

Il existe de nombreux autres bons ORM. Surtout Hibernate ou iBATIS ont une grande communauté. Mais si vous êtes à la recherche d'une solution intuitive et simple, je dirai d'essayer jOOQ. Tu l'adoreras! :-)

Découvrez cet exemple SQL:

  // Select authors with books that are sold out
  SELECT * 
    FROM T_AUTHOR a
   WHERE EXISTS (SELECT 1
                   FROM T_BOOK
                  WHERE T_BOOK.STATUS = 'SOLD OUT'
                    AND T_BOOK.AUTHOR_ID = a.ID);

Et comment cela peut être exprimé en jOOQ:

  // Alias the author table
  TAuthor a = T_AUTHOR.as("a");

  // Use the aliased table in the select statement
  create.selectFrom(a)
        .whereExists(create.selectOne()
                           .from(T_BOOK)
                           .where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
                           .and(T_BOOK.AUTHOR_ID.equal(a.ID))))));
Lukas Eder
la source
1
Les outils ORM sont aussi efficaces que vous parvenez à les utiliser correctement. Il y a des projets où les outils ORM fonctionnent comme des charmes, tandis que dans d'autres, ils ne correspondent pas du tout. En fin de compte, c'est la responsabilité de l'équipe de développement de choisir le bon outil pour les exigences de leur projet. Les outils ORM sont complexes. Malheureusement, seule une partie de tous les développeurs passera du temps à comprendre comment ils fonctionnent. Le reste ne fera que blâmer l'outil et dire qu'il est mauvais. La question est: la réponse la plus votée offre-t-elle le meilleur conseil? > Envisagez donc d'utiliser uniquement le package JDBC. Voulons-nous vraiment utiliser du JDBC ordinaire?
Vlad Mihalcea
J'essaye de ne pas laisser "La base de données vient en premier". Une application contient les règles métier des fonctionnalités demandées par un client et il ne demande presque jamais de créer une base de données. C'est un détail technique déterminé lors de la mise en œuvre.
Kwebble du
58

Hibernate, car il s'agit essentiellement de la norme de facto en Java et a été l'un des moteurs de la création de la JPA. Il a un excellent support dans Spring, et presque tous les frameworks Java le supportent. Enfin, GORM est un wrapper vraiment cool autour de lui faisant des trouveurs dynamiques et ainsi de suite en utilisant Groovy.

Il a même été porté sur .NET (NHibernate) afin que vous puissiez également l'utiliser là-bas.

Abdullah Jibaly
la source
4
Je vote également Hib, mais avec un ajout important: nous ne devons utiliser l'API JPA que même si la mise en œuvre de JPA est en fait fournie par Hib.
Vladimir Dyuzhev
52

Hibernate, car il:

  • est stable - existe depuis tant d'années, il ne présente aucun problème majeur
  • dicte les normes dans le domaine ORM
  • met en œuvre la norme (JPA), en plus de la dicter.
  • a des tonnes d'informations à ce sujet sur Internet. Il existe de nombreux didacticiels, solutions aux problèmes courants, etc.
  • est puissant - vous pouvez traduire un modèle objet très complexe en un modèle relationnel.
  • il prend en charge tous les SGBDR majeurs et moyens
  • est facile à travailler, une fois que vous l'avez bien appris

Quelques points sur pourquoi (et quand) utiliser ORM:

  • vous travaillez avec des objets dans votre système (si votre système a été bien conçu). Même si vous utilisez JDBC, vous finirez par créer une couche de traduction, afin de transférer vos données vers vos objets. Mais mes paris sont que l'hibernation est meilleure en traduction que n'importe quelle solution sur mesure.
  • cela ne vous prive pas de contrôle. Vous pouvez contrôler les choses dans de très petits détails, et si l'API n'a pas de fonctionnalité distante - exécutez une requête native et vous l'avez.
  • tout système de taille moyenne ou plus grande ne peut pas se permettre d'avoir une tonne de requêtes (que ce soit à un endroit ou dispersées à travers), s'il vise à être maintenable
  • si les performances ne sont pas critiques. Hibernate ajoute une surcharge de performances, qui dans certains cas ne peut pas être ignorée.
Bozho
la source
Quand je compare Hibernate et JPA, je choisis Hibernate, et si je compare JPA et JDO, je choisis JDO! J'aime beaucoup JDO, mais j'aime deux fonctionnalités d'Hibernate (qui ne sont pas disponibles dans JDO), l'une est @Filters et l'autre est que vous pouvez mapper des champs de version (pour un verrouillage optimiste) dans des champs normaux, ce qui n'est pas possible dans JDO .
Amir Pashazadeh
27

Je recommanderais d'utiliser MyBatis . C'est une couche mince au-dessus de JDBC, il est très facile de mapper des objets aux tables et d'utiliser toujours du SQL simple, tout est sous votre contrôle.

adrian.tarau
la source
10
Ibatis pour les lectures complexes et l'hibernation pour la création, la mise à jour, la suppression et les lectures simples est un choix parfait.
darpet
19

J'ai eu une très bonne expérience avec Avaje Ebean lorsque j'écrivais une application JavaSE de taille moyenne.

Il utilise des annotations JPA standard pour définir les entités, mais expose une API beaucoup plus simple (pas d'entitéManager ou n'importe laquelle de ces entités attachées / détachées). Il vous permet également d'utiliser facilement des requêtes SQL ou des appels JDBC simples en cas d'événement.

Il dispose également d'une très belle API fluide et sécurisée pour les requêtes. Vous pouvez écrire des choses comme:

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();
IgKh
la source
6
Je dois être un peu bizarre ... choisir parmi Personne où le sexe = 'M' et l'âge <18 commandé par firstName me semble tellement mieux :-)
Eelco
4
C'est l'un des meilleurs ormes que j'ai vus en java. Sa décision d'utiliser un singleton est rafraîchissante et lui donne un énorme avantage pratique sur les autres.
opsb
Je pense que vous parlez couramment et non fluide.
Montdidier
@opsb Je pense que techniquement c'est un monostate, pas un singleton.
Montdidier
Comment démarrer avec Avaje Ebean ORM? Des vidéos Tutoriels ??
Avinash
11

SimpleORM , car il est simple et sans magie. Il définit toutes les structures de métadonnées en code Java et est très flexible.

SimpleORM fournit des fonctionnalités similaires à Hibernate en mappant les données d'une base de données relationnelle aux objets Java en mémoire. Les requêtes peuvent être spécifiées en termes d'objets Java, l'identité de l'objet est alignée sur les clés de la base de données, les relations entre les objets sont conservées et les objets modifiés sont automatiquement vidés dans la base de données avec des verrous optimistes.

Mais contrairement à Hibernate, SimpleORM utilise une structure et une architecture d'objet très simples qui évitent le besoin d'analyses complexes, de traitement de code d'octets, etc. dépendance (Slf4j). (La mise en veille prolongée dépasse 2400 Ko et environ 2000 Ko de pots dépendants.) Cela rend SimpleORM facile à comprendre et réduit ainsi considérablement les risques techniques.

David Schmitt
la source
Je ne l'ai pas utilisé, mais ActiveObjects se décrit comme une sorte d'Hibernate-lite sur leur site Web, il y a donc probablement une certaine similitude.
Abdullah Jibaly
10

Eclipse Link , pour de nombreuses raisons, mais j'ai notamment l'impression qu'il a moins de ballonnement que les autres solutions de flux principal (au moins moins de ballonnement en direct).

Oh et Eclipse Link a été choisi pour être l'implémentation de référence pour JPA 2.0

Tom Neyland
la source
5

Bien que je partage les préoccupations concernant les remplacements Java pour les requêtes SQL de forme libre, je pense vraiment que les gens critiquant ORM le font en raison d'une conception d'application généralement médiocre.

True OOD est piloté par des classes et des relations, et ORM vous offre un mappage cohérent de différents types de relations et d'objets. Si vous utilisez un outil ORM et que vous finissez par coder des expressions de requête dans le langage de requête pris en charge par le cadre ORM (y compris, mais sans s'y limiter, les arborescences d'expression Java, les méthodes de requête, OQL, etc.), vous faites définitivement quelque chose de mal, c'est-à-dire votre modèle de classe ne répond probablement pas à vos besoins comme il se doit. Une conception d'application propre n'a pas vraiment besoin de requêtes au niveau de l'application. J'ai refactorisé de nombreux projets que les gens ont commencé à utiliser un cadre ORM de la même manière qu'ils ont été utilisés pour incorporer des constantes de chaîne SQL dans leur code, et à la fin, tout le monde a été surpris de la simplicité et de la maintenabilité de l'ensemble de l'application une fois que vous correspondez votre modèle de classe avec le modèle d'utilisation. Certes, pour des choses telles que la fonctionnalité de recherche, etc., vous avez besoin d'un langage de requête, mais même dans ce cas, les requêtes sont tellement limitées que la création d'une VUE et d'un mappage encore plus complexes à une classe persistante en lecture seule est beaucoup plus agréable à maintenir et à regarder que la construction d'expressions. dans un langage de requête dans le code de votre application. L'approche VIEW exploite également les capacités de la base de données et, via la matérialisation, peut être bien meilleure en termes de performances que n'importe quel SQL manuscrit dans votre source Java. Donc, je ne vois aucune raison pour qu'une application non triviale NE PAS utiliser ORM. mais même dans ce cas, les requêtes sont tellement limitées que la création d'une VUE encore plus complexe et le mappage à une classe persistante en lecture seule est beaucoup plus agréable à gérer et à regarder que de créer des expressions dans un langage de requête dans le code de votre application. L'approche VIEW exploite également les capacités de la base de données et, via la matérialisation, peut être bien meilleure en termes de performances que n'importe quel SQL manuscrit dans votre source Java. Donc, je ne vois aucune raison pour qu'une application non triviale NE PAS utiliser ORM. mais même dans ce cas, les requêtes sont tellement limitées que la création d'une VUE encore plus complexe et le mappage à une classe persistante en lecture seule est beaucoup plus agréable à gérer et à regarder que de créer des expressions dans un langage de requête dans le code de votre application. L'approche VIEW exploite également les capacités de la base de données et, via la matérialisation, peut être bien meilleure en termes de performances que n'importe quel SQL manuscrit dans votre source Java. Donc, je ne vois aucune raison pour qu'une application non triviale NE PAS utiliser ORM.

Mirko Klemm
la source
11
Si vous créez des applications au-dessus d'un magasin persistant, comme beaucoup d'entre nous, que ce soit un SGBDR ou une version NoSQL, ce magasin aura sa propre manière efficace d'y accéder. Essayer de trop en faire abstraction est simplement une ingénierie excessive. Être trop zélé à propos du «vrai OOD» obtient ces architectures d'astronautes pour lesquelles Java est tristement célèbre.
Eelco