¿Qué ORM de Java prefieres y por qué? [cerrado]

262

Es una pregunta bastante abierta. Comenzaré un nuevo proyecto y estoy mirando diferentes ORM para integrar con el acceso a la base de datos.

¿Tienes algún favorito? ¿Hay alguna que le aconseje mantenerse alejado?

Tom Neyland
fuente
Eche un vistazo a los microorms: envoltorios delgados alrededor de la tecnología de acceso a la base de datos de la plataforma, como sql2o para Java github.com/aaberg/sql2o o ServiceStack.OrmLite para .NET github.com/ServiceStack/ServiceStack.OrmLite
tomaszkubacki
3
Después de usar ORM durante más de 5 años, mi elección personal es Spring JDBC sobre ORM, y el segundo mejor es iBatis (MyBatis), no me gusta la hibernación debido a la curva de aprendizaje, menos problemas de control y rendimiento.
Aquí hay una lista (también cerrada) de envoltorios jdbc livianos que se pueden usar como alternativa a los orms completos: stackoverflow.com/questions/7137929/…
Vadzim

Respuestas:

237

He dejado de usar ORM.

La razón no es ningún gran defecto en el concepto. Hibernate funciona bien. En cambio, descubrí que las consultas tienen una sobrecarga baja y puedo ajustar mucha lógica compleja en consultas SQL grandes, y transferir gran parte de mi procesamiento a la base de datos.

Así que considere usar el paquete JDBC.

David Crawshaw
fuente
81
Es la misma historia una y otra vez con ORM: desarrollo inicial rápido y agradable, y una gran pérdida de recursos más adelante en el proyecto al rastrear errores e ineficiencias relacionadas con ORM. También odio el hecho de que parece dar a los desarrolladores la idea de que nunca tienen que escribir consultas optimizadas específicas.
Eelco
77
Oye, ¿es todo esto cierto para grandes proyectos de la vida real?
santiagobasulto
30
Estoy de acuerdo. He estado usando ORM durante más de 3 años, y no puedo decir cuánto tiempo se perdió (todavía lo es) para resolver problemas relacionados con la persistencia. No tenemos ningún control sobre lo que está sucediendo "bajo el capó", las configuraciones son demasiadas para ser administradas de manera eficiente y hay comportamientos que podrían volverlo loco. Por otro lado, tengo soporte para las principales bases de datos y nunca tengo que preocuparme por sus diferencias.
marcolopes
58
¿por qué no usar ambos, dependiendo de la complejidad de la consulta / transacción? No es que sean mutuamente excluyentes.
anfibio
66
@ WillSheppard sí Will. Yo uso Django ORM bastante y funciona muy bien. Creo que la diferencia podría estar en la naturaleza dinámica de python (y perl). Usar un ORM en Java es un dolor. Pero en lenguajes dinámicos puede ser realmente expresivo. Hay algunos grandes proyectos para integrar operaciones ORM como DSL en Python y son geniales.
santiagobasulto
97

Ninguno, porque tener un ORM quita demasiado control con pequeños beneficios. Los ahorros de tiempo ganados se eliminan fácilmente cuando tiene que depurar anomalías resultantes del uso del ORM. Además, los ORM desalientan a los desarrolladores a aprender SQL y cómo funcionan las bases de datos relacionales y usar esto para su beneficio.

Simón
fuente
44
Concuerdo con esta declaración. ¿Cuánto del tiempo total de desarrollo se consumirá escribiendo código de persistencia? Creo que menos del 10-15%
adrian.tarau
16
Depende. Claro, si está usando solo un tipo particular de base de datos, es fácil salirse con la suya al no usar un ORM. Sin embargo, cuando necesita admitir otros tipos de bases de datos, puede volverse menos manejable rápidamente.
Jason Baker el
3
"Los ahorros de tiempo ganados se eliminan fácilmente cuando tienes que depurar anomalías resultantes del uso del ORM" Esto no es cierto cuando la curva de habilidades es un factor decente al tomar decisiones tecnológicas.
elsadek
77
Su argumento podría ser ofrecido contra el uso de cualquier biblioteca. Las mayores ganancias de los ORM son cosas como unidades de trabajo, mapeo de objetos, seguimiento de cambios, carga diferida, migraciones y relaciones. Es maravilloso poder escribir user.profile.givenName y no preocuparse por la estructura utilizada para almacenar los datos.
Alex
1
Podría usarse contra cualquier biblioteca, pero en distintos grados. En general, soy un gran defensor del uso de bibliotecas: ¿por qué reinventar la rueda? Sin embargo, en este caso, creo que Hibernate es para la mayoría de los usos un peso demasiado pesado y un ORM más liviano sería más preferible. Mis experiencias se basan en varios años de experiencia desarrollando con Hibernate y aprendiendo a fondo sus entresijos.
Simon
92

Muchos ORM son geniales, necesita saber por qué desea agregar abstracción sobre JDBC. Puedo recomendarle http://www.jooq.org (descargo de responsabilidad: soy el creador de jOOQ, por lo que esta respuesta es parcial). jOOQ adopta el siguiente paradigma:

  • SQL es algo bueno. Muchas cosas se pueden expresar muy bien en SQL. No hay necesidad de abstracción completa de SQL.
  • El modelo de datos relacionales es algo bueno. Ha demostrado ser el mejor modelo de datos de los últimos 40 años. No hay necesidad de bases de datos XML o modelos de datos verdaderamente orientados a objetos. En cambio, su empresa ejecuta varias instancias de Oracle, MySQL, MSSQL, DB2 o cualquier otro RDBMS.
  • SQL tiene una estructura y sintaxis. No debe expresarse utilizando la concatenación de cadenas de "bajo nivel" en JDBC, o la concatenación de cadenas de "alto nivel" en HQL, que son propensas a contener errores de sintaxis.
  • El enlace variable tiende a ser muy complejo cuando se trata de consultas importantes. ESO es algo que debería ser abstraído.
  • Los POJO son excelentes al escribir código Java manipulando datos de la base de datos.
  • Los POJO son difíciles de escribir y mantener manualmente. La generación de código es el camino a seguir. Tendrá consultas seguras para la compilación, incluida la seguridad del tipo de datos.
  • La base de datos es lo primero. Si bien la aplicación en la parte superior de su base de datos puede cambiar con el tiempo, la base de datos en sí misma probablemente durará más.
  • Sí, tiene procedimientos almacenados y tipos definidos por el usuario (UDT) en su base de datos heredada. Su herramienta de base de datos debería soportar eso.

Hay muchos otros buenos ORM. Especialmente Hibernate o iBATIS tienen una gran comunidad. Pero si está buscando una intuitiva y simple, le diré que pruebe jOOQ. ¡Te va a encantar! :-)

Mira este ejemplo de 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);

Y cómo se puede expresar 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
fuente
1
Las herramientas ORM son tan buenas como puedes usarlas correctamente. Hay proyectos en los que las herramientas ORM funcionan como encantos, mientras que en otros, no encajan bien en absoluto. Al final, es responsabilidad del equipo de desarrollo elegir la herramienta adecuada para los requisitos de su proyecto. Las herramientas ORM son complejas. Desafortunadamente, solo una parte de todos los desarrolladores pasará tiempo para comprender cómo funcionan. El resto simplemente culpará a la herramienta y dirá que es mala. La pregunta es: ¿la respuesta más votada ofrece el mejor consejo? > Así que considera usar el paquete JDBC. ¿Realmente queremos usar JDBC simple?
Vlad Mihalcea
Intento no dejar que "La base de datos sea lo primero". Una aplicación contiene las reglas de negocio para las características que solicita un cliente y casi nunca solicitan crear una base de datos. Ese es un detalle técnico determinado durante la implementación.
Kwebble
58

Hibernate, porque es básicamente el estándar de facto en Java y fue una de las fuerzas impulsoras en la creación de la JPA. Tiene un excelente soporte en Spring, y casi todos los frameworks de Java lo admiten. Finalmente, GORM es una envoltura realmente genial a su alrededor que hace buscadores dinámicos y así sucesivamente usando Groovy.

Incluso se ha portado a .NET (NHibernate) para que pueda usarlo allí también.

Abdullah Jibaly
fuente
44
También voto por Hib, pero con una adición importante: deberíamos usar la API de JPA solo si Hib proporciona la implementación de JPA.
Vladimir Dyuzhev el
52

Hibernate, porque:

  • es estable: existe desde hace tantos años que carece de problemas importantes
  • dicta los estándares en el campo ORM
  • implementa el estándar (JPA), además de dictarlo.
  • tiene toneladas de información al respecto en Internet. Hay muchos tutoriales, soluciones de problemas comunes, etc.
  • es poderoso: puede traducir un modelo de objeto muy complejo en un modelo relacional.
  • tiene soporte para cualquier RDBMS mayor y medio
  • es fácil trabajar con él, una vez que lo aprendes bien

Algunos puntos sobre por qué (y cuándo) usar ORM:

  • trabaja con objetos en su sistema (si su sistema se ha diseñado bien). Incluso si usa JDBC, terminará haciendo una capa de traducción, de modo que transfiera sus datos a sus objetos. Pero mis apuestas son que hibernar es mejor en traducción que cualquier solución personalizada.
  • No te priva del control. Puede controlar las cosas con detalles muy pequeños, y si la API no tiene alguna función remota, ejecute una consulta nativa y la tendrá.
  • cualquier sistema de tamaño mediano o grande no puede permitirse el lujo de tener una tonelada de consultas (ya sea en un lugar o dispersas), si pretende ser mantenible
  • Si el rendimiento no es crítico. Hibernate agrega sobrecarga de rendimiento, que en algunos casos no se puede ignorar.
Bozho
fuente
Cuando comparo Hibernate y JPA, voy por Hibernate, y si comparo JPA y JDO, ¡voy por JDO! Me gusta mucho JDO, pero me encantan dos características de Hibernate (que no están disponibles en JDO), una es @Filters y la otra es que puedes asignar campos de versión (para un bloqueo optimista) en campos normales, lo cual no es posible en JDO .
Amir Pashazadeh
27

Yo recomendaría usar MyBatis . Es una capa delgada encima de JDBC, es muy fácil asignar objetos a tablas y aún usar SQL simple, todo está bajo su control.

adrian.tarau
fuente
10
Ibatis para lecturas complejas e hibernar para crear, actualizar, eliminar y lecturas simples es la elección perfecta.
darpet
19

Tuve una muy buena experiencia con Avaje Ebean cuando estaba escribiendo una aplicación JavaSE de tamaño mediano.

Utiliza anotaciones JPA estándar para definir entidades, pero expone una API mucho más simple (No EntityManager o cualquiera de esas basura de entidades adjuntas / desconectadas). También le permite usar fácilmente consultas SQL o llamadas JDBC de eventos simples cuando sea necesario.

También tiene una API muy fluida y segura para escribir para consultas. Puedes escribir cosas como:

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();
IgKh
fuente
66
Debo ser un poco raro ... seleccione de Persona donde género = 'M' y edad <18 ordenado por firstName me parece mucho mejor :-)
Eelco
44
Esta es una de las mejores formas que he visto en Java. Su decisión de usar un singleton es refrescante y le da una ventaja práctica masiva sobre los demás.
opsb
Creo que te refieres a fluido, no fluido.
Montdidier
@opsb Creo que técnicamente es un monostate, no un singleton.
Montdidier
¿Cómo comenzar con Avaje Ebean ORM? ¿Algún video Tutoriales?
Avinash
11

SimpleORM , porque es sencillo y sin magia. Define todas las estructuras de metadatos en código Java y es muy flexible.

SimpleORM proporciona una funcionalidad similar a Hibernate al asignar datos en una base de datos relacional a objetos Java en la memoria. Las consultas se pueden especificar en términos de objetos Java, la identidad del objeto se alinea con las claves de la base de datos, las relaciones entre los objetos se mantienen y los objetos modificados se enjuagan automáticamente a la base de datos con bloqueos optimistas.

Pero a diferencia de Hibernate, SimpleORM utiliza una estructura y arquitectura de objetos muy simples que evitan la necesidad de análisis complejos, procesamiento de código de bytes, etc. dependencia (Slf4j). (Hibernate tiene más de 2400 K más unos 2000 K de jarras dependientes). Esto hace que SimpleORM sea fácil de entender y reduce en gran medida el riesgo técnico.

David Schmitt
fuente
No lo he usado, pero ActiveObjects se describe a sí mismo como una especie de Hibernate-lite en su sitio web, por lo que probablemente haya alguna similitud.
Abdullah Jibaly
10

Eclipse Link , por muchas razones, pero notablemente siento que tiene menos hinchazón que otras soluciones principales (al menos menos hinchazón en la cara).

Oh y Eclipse Link ha sido elegido para ser la implementación de referencia para JPA 2.0

Tom Neyland
fuente
5

Si bien comparto las preocupaciones con respecto a los reemplazos de Java para consultas SQL de forma libre, realmente creo que las personas que critican a ORM lo están haciendo debido a un diseño de aplicación generalmente pobre.

El verdadero OOD está impulsado por clases y relaciones, y ORM le ofrece un mapeo consistente de diferentes tipos de relaciones y objetos. Si utiliza una herramienta ORM y termina codificando expresiones de consulta en cualquier lenguaje de consulta que admita el marco ORM (incluidos, entre otros, árboles de expresiones Java, métodos de consulta, OQL, etc.), definitivamente está haciendo algo mal, es decir, su modelo de clase lo más probable es que no respalde sus requisitos de la manera que debería. Un diseño de aplicación limpio realmente no necesita consultas a nivel de aplicación. He estado refactorizando muchos proyectos que la gente comenzó a usar un marco ORM de la misma manera que se usaban para incrustar constantes de cadena SQL en su código, y al final todos quedaron sorprendidos de lo simple y fácil de mantener que toda la aplicación se vuelve una vez que coinciden sube tu modelo de clase con el modelo de uso. Por supuesto, para cosas como la funcionalidad de búsqueda, etc., necesita un lenguaje de consulta, pero aun así las consultas están tan limitadas que crear una VISIÓN y mapeo aún más complejo que a una clase persistente de solo lectura es mucho más agradable de mantener y mirar que construir expresiones en algún lenguaje de consulta en el código de su aplicación. El enfoque VIEW también aprovecha las capacidades de la base de datos y, a través de la materialización, puede ser mucho mejor en términos de rendimiento que cualquier SQL escrito a mano en su fuente Java. Por lo tanto, no veo ninguna razón para que una aplicación no trivial NO use ORM. pero incluso entonces las consultas están tan limitadas que crear una VIEW y un mapeo aún más complejos que a una clase persistente de solo lectura es mucho más agradable de mantener y observar que construir expresiones en algún lenguaje de consulta en el código de su aplicación. El enfoque VIEW también aprovecha las capacidades de la base de datos y, a través de la materialización, puede ser mucho mejor en términos de rendimiento que cualquier SQL escrito a mano en su fuente Java. Por lo tanto, no veo ninguna razón para que una aplicación no trivial NO use ORM. pero incluso entonces las consultas están tan limitadas que crear una VIEW y un mapeo aún más complejos que a una clase persistente de solo lectura es mucho más agradable de mantener y observar que construir expresiones en algún lenguaje de consulta en el código de su aplicación. El enfoque VIEW también aprovecha las capacidades de la base de datos y, a través de la materialización, puede ser mucho mejor en términos de rendimiento que cualquier SQL escrito a mano en su fuente Java. Por lo tanto, no veo ninguna razón para que una aplicación no trivial NO use ORM.

Mirko Klemm
fuente
11
Si está creando aplicaciones sobre una tienda persistente, como muchos de nosotros, ya sea un RDBMS o algún sabor NoSQL, esa tienda tendrá su propia forma eficiente de acceder a ella. Tratar de abstraerse de eso demasiado es solo una ingeniería excesiva. Ser demasiado celoso sobre el "verdadero OOD" consigue esas arquitecturas de astronautas por las que Java es infame.
Eelco