Cómo Hibernate casi arruinó mi carrera

Publicado: 2022-03-11

Imagina que eres un desarrollador de Java y estás a punto de comenzar tu próximo gran proyecto. Necesitas tomar las decisiones fundamentales que te acompañarán durante el resto del proyecto. Desea elegir la mejor abstracción orientada a objetos de su modelo de datos flexible porque no desea tratar con SQL simple. Desea admitir todo tipo de datos e, idealmente, admitir todo tipo de bases de datos.

La respuesta obvia es simplemente usar Hibernate , ¿verdad? El 90% de los desarrolladores de Java estarían de acuerdo contigo, pero ¿eso hace que sea la decisión correcta?

Echemos un vistazo a lo que puede salir mal si usa Hibernate a ciegas solo porque es el estándar aceptado.

Considere a Monica, una desarrolladora de Java. Mónica fue ascendida recientemente al puesto de arquitecta y ahora es responsable de diseñar la pila de tecnología para un nuevo producto en su empresa. Sabe que en el mundo de Java solo existe una buena herramienta para manejar la comunicación de bases de datos: Hibernate . Hibernate es un estándar JPA bien conocido y compatible. Sin embargo, siempre es una buena idea verificar algunas cosas antes de comenzar un proyecto. Afortunadamente, su colega, Ben, conoce al hombre adecuado.

Hibernate suena como una bala de plata

Hace 4 años

Ben - Hola Mónica, me gustaría presentarles a John. Es un experto en Hibernate y te ayudará.

Monica - Hola John, me alegro de que hayas encontrado algo de tiempo para mí. Entonces, estamos construyendo nuestra Próxima Gran Cosa, ya sabes. Estamos planeando convertirnos en el próximo Facebook o Google. Días ocupados. Va a ser enorme. ¡Absolutamente fantástico! ¡Todos están tan emocionados! Fui ascendido al rol de arquitecto, por lo que ahora debo seleccionar la pila que usaremos. Lo único que falta es la persistencia…

John- ¡ Hibernar !

Mónica - ¡Sí! ¡Exactamente! ¡Justo lo que estaba pensando! Parece una combinación perfecta y el verdadero negocio para nosotros. Una verdadera solución empresarial para un verdadero problema empresarial, probada por el mercado y con una larga trayectoria. He oído muchas experiencias positivas con él. Sin embargo, tengo un problema con uno de nuestros compañeros de equipo; él está totalmente en contra. Sabe mucho sobre bases de datos y tiene miedo de agregar otra capa entre nuestra aplicación y la base de datos. Es súper inteligente y necesito buenos argumentos para convencerlo de que es una buena decisión. ¿Me puede ayudar con eso?

Juan- ¡Claro! Estaré encantado de. Hibernate es, de hecho, una herramienta excepcional. Se usa ampliamente en grandes soluciones empresariales reales, como los bancos. No puedes equivocarte con eso. Piense en la persistencia: Elija Hibernate . Si está escribiendo en Java, esta es absolutamente la elección correcta, además tiene puertos para otros idiomas. ¡Vea cuántas descripciones de trabajo lo requieren!

Mónica - ¡Totalmente de acuerdo! Tengo los mismos sentimientos al respecto. En un proyecto anterior, usábamos principalmente SQL a través de JDBC simple y antiguo. ¡Ridículo! ¡Sé! Pero, aquí está la cosa: tenemos chicos de SQL realmente inteligentes en el equipo y cuando vieron SQL generado por Hibernate se pusieron nerviosos. Parecía feo e ilegible; ¿Será esto un problema en el futuro?

Juan- Mira. Los chicos de DBA tienen una perspectiva diferente. Tienen miedo de Hibernate porque parece reemplazar su papel en el proyecto. Además, las bases de datos tienen optimizadores de consultas incorporados, por lo que no debe preocuparse por cómo se verán realmente esas consultas. La base de datos lo optimizará para usted. Se trata de un desarrollo rápido, algo que SQL no puede hacer.

Mónica- ¿En serio? ¿Ya no trata con SQL? ¡Asombroso! La última vez que un DBA pasó semanas tratando de optimizar algunas consultas. ¡Semanas! Oh, me da tanta vergüenza decirte esto, pero ¿sabías que estábamos usando... procedimientos almacenados (risas)? Oh, fue un desastre. ¿Puedes creer que el proyecto todavía lo está usando? Lo siento mucho por la gente de ahí. Todavía tienen que escribir este tedioso código una y otra vez. Me pregunto si todavía es un proyecto Java o SQL.

John : Esa es exactamente la diferencia entre un enfoque orientado a objetos y uno relacional. Es el llamado desajuste de impedancia orientado a objetos. Hibernate puede cerrar esta brecha. Los desarrolladores pueden centrarse en crear una lógica empresarial. Las funciones push hacen felices a las partes interesadas y a toda la administración. Haz las cosas que más importan: ¡Negocios! Desaparecerá una gran cantidad de código repetitivo y tendrá una conexión mágica, invisible, pero confiable, entre la lógica y los datos.

Mónica - Cooperación mutua. Sinergia total. Como si la base de datos fuera parte del lenguaje desde el principio. Estoy tan feliz de poder ser un líder de este salto tecnológico de fe. Es como la velocidad warp en el viaje del software.

Juan- ¡Sí! ¡Tu lo tienes!

Monica - ¡Dios mío, estoy tan emocionada! ¡Gracias John! ¡Estoy listo!

Hibernate no es una panacea. No lo trate como su solución de base de datos predeterminada.
Pío

Problemas de crecimiento con soluciones no flexibles

hace 3 años

Monica - Hola John, ¿recuerdas el proyecto del que hablamos el año pasado?

Juan- Claro. ¿Cómo te va?

Monica - Vamos a empezar la producción pronto. Todo está bien, pero han aparecido algunas preguntas.

Juan - Claro, pégame.

Monica - Bueno, ya no podemos generar nuestro esquema de base de datos desde cero. ¿Cuál es la mejor manera de admitir cambios de esquema sin perder datos?

John : Bueno, en primer lugar, Hibernate no está destinado a ser utilizado como una herramienta de migración de producción. Usa algo como FlywayDB o Liquibase. Es bastante simple. Escribe los scripts de migración, luego actualiza el modelo de entidad junto con las asignaciones de Hibernate , para que se mantenga sincronizado con la estructura de la base de datos real.

Monica - Hmm, ya veo. Estábamos usando simplemente la migración de SQL en el proyecto anterior.

Juan - Eso también está bien. Siempre que mantenga el modelo de entidad y el esquema sincronizados, hágalo como desee.

Mónica - Ya veo. Hay otra cosa. Siempre estamos luchando con problemas de búsqueda perezosos/ansiosos. En un momento decidimos hacer todo con ganas, pero parece subóptimo, y además, a veces no es posible acceder a algunos campos porque no hay sesión, o algo así. ¿Eso es normal?

John : debe aprender más sobre Hibernate . El mapeo desde la base de datos no es sencillo. Básicamente, hay múltiples formas de hacerlo. Solo necesita elegir una forma que funcione para usted. La búsqueda diferida le brinda la capacidad de cargar esos objetos a pedido, pero debe operar dentro de una sesión activa.

Monica : Todavía estamos luchando con qué motor de base de datos usar para la implementación final. Pensé que Hibernate era portátil, pero tenemos algunas consultas nativas que usan algo de magia de MS SQL, y de hecho nos gustaría usar MySQL en la producción.

John : Hibernate le brinda flexibilidad siempre que use criterios separados o HQL; cualquier consulta nativa simplemente vinculará su solución a la base de datos.

Monica : Parece que entonces tenemos que ceñirnos a MS SQL. Última pregunta: mi compañero de equipo dijo que no hay una palabra clave de "límite" en HQL. Pensé que estaba bromeando, pero tampoco pude encontrarlo. Perdón por la estúpida pregunta…

John - De hecho, no existe una palabra clave de "límite" en HQL. Puede controlar esto a través del objeto de consulta, ya que es específico del proveedor de la base de datos.

Monica - Parece extraño que todos los demás elementos estén en HQL. No importa. ¡Gracias por tu tiempo!

Relacionado: Cómo crear una aplicación multiusuario: un tutorial de Hibernate

Ahora estamos hackeando juntos soluciones en SQL de nuevo

Hace 2 años

Monica - John, al principio no íbamos a tratar con SQL, pero ahora parece que tenemos que hacerlo. Nuestras necesidades están creciendo, y parece que no hay forma de evitarlo. Se siente mal, pero comenzamos a usar SQL nuevamente a diario.

John - Bueno, no está mal. No tenía que concentrarse en la base de datos desde el principio. Sin embargo, a medida que crece el proyecto, es bueno usar SQL y trabajar en la optimización del rendimiento.

Monica - A veces nos pasamos días buscando errores. Parece que tenemos que analizar el SQL generado por Hibernate porque no tenemos idea de por qué no funciona como se esperaba y produce resultados inesperados. Nos encontramos con algunos problemas que son bien conocidos en el rastreador de errores de Hibernate . Además, es difícil escribir migraciones adecuadas mientras se mantiene sincronizado el modelo de entidad. Lleva mucho tiempo, ya que necesitamos aprender mucho sobre los componentes internos de Hibernate y predecir cómo funcionará.

John - Siempre hay una curva de aprendizaje. No tienes que escribir mucho, pero necesitas saber cómo funciona.

Monica - Trabajar con conjuntos de datos más grandes también es molesto. Recientemente, hicimos una importación masiva a la base de datos, y fue terriblemente lenta. Luego descubrimos que teníamos que borrar la sesión para que fuera más rápida. Aun así, sigue siendo significativamente más lento, por lo que decidimos reescribirlo como declaraciones SQL simples. Lo divertido es que escribir SQL simple era en realidad la forma más rápida de hacerlo, así que decidimos hacerlo como nuestra última opción.

John : la importación no es un proceso orientado a objetos. Hibernate se centra en el diseño orientado a objetos. Recuerda que siempre puedes usar consultas nativas.

Monica - ¿Puedes ayudarme a entender cómo funciona el caché de Hibernate ? Simplemente no entiendo. Hay algunos cachés de primer/segundo nivel. ¿Qué es todo esto?

Juan- Claro. Es el llamado caché a nivel de transacción de datos persistentes. Es posible configurar un caché de nivel de clúster o JVM en una base de clase por clase y colección por colección. Incluso puede conectar un caché en clúster. Pero recuerde que los cachés no son conscientes de ningún cambio realizado en el almacén persistente por otra aplicación. Sin embargo, se pueden configurar para eliminar regularmente los datos caducados en caché.

Monica - Lo siento, creo que estoy teniendo un mal día. ¿Puedes explicar esto un poco más?

Juan- Claro. Cada vez que pasa un objeto para save , update , saveOrUpdate o actualizar o recuperarlo a través de load , get , list , iterate o scroll , ese objeto se agrega al caché interno de la sesión. También puede eliminar el objeto y sus colecciones de la memoria caché de primer nivel.

Mónica - Eh…

John : además, puede controlar los modos de caché. Puede usar el modo normal para leer y escribir elementos en la memoria caché de segundo nivel. Use el modo get para leer desde el segundo nivel, pero no puede volver a escribir. Use put , que es lo mismo que get pero no puede leer desde el segundo nivel. También puede usar el modo de refresh , que escribirá en el segundo nivel, pero no leerá de él y omitirá la propiedad de use minimal puts , forzando una actualización del caché de segundo nivel para todos los elementos leídos de la base de datos.

Mónica - Ya veo. Está bien. Déjame pensar acerca de esto. Oh, es tarde, tengo que irme. ¡Gracias por tu tiempo!

Juan- ¡De nada!

Renunciar a Hibernate

hace 2 semanas

Monica - John, pensé que estábamos entrando en una nueva era de desarrollo de software. Pensé que estábamos dando un salto de un año luz. Pero, después de cuatro años, parece que todavía estamos lidiando con los mismos problemas, solo que desde un ángulo diferente. Tuve que aprender arquitectura Hibernate , configuración, registro, estrategias de nombres, tuplizers, solucionadores de nombres de entidades, generadores de identificadores mejorados, optimización de generadores de identificadores, subclases de unión, marcado XDoclet, asociaciones bidireccionales con colecciones indexadas, asociaciones ternarias, idbag, mezclando polimorfismo implícito con otras asignaciones de herencia, replicación de objetos entre dos almacenes de datos diferentes, objetos separados y control de versiones automático, modos de liberación de conexión, interfaz de sesión sin estado, taxonomía de persistencia de colección, niveles de caché, búsqueda perezosa o ansiosa y mucho, mucho más. Incluso con todo lo que sé, parece que hemos fallado gravemente. ¡Es un fiasco de software! ¡Fracaso definitivo! ¡Desastre! ¡Armagedón!

Juan- ¡Espera! ¿Qué sucedió?

Monica - Hemos llegado a un callejón sin salida. ¡El rendimiento de nuestra aplicación es ridículamente lento! ¡Para obtener un informe, tenemos que esperar dos días! Dos días para generar realmente un tablero para un cliente. Significa que todos los días tenemos que aumentar nuestra cola de cálculo, mientras que nuestro tablero se vuelve más y más desactualizado. Nuestro experto DBA ha estado trabajando dos meses para optimizar algunas consultas, mientras que la estructura de nuestra base de datos es un completo desastre. Hay desarrolladores que lo respaldan, pero el problema es que el DBA está pensando en SQL, y los desarrolladores pasan días tratando de traducir esto en criterios independientes o formato HQL. Estamos tratando de usar SQL nativo tanto como sea posible ya que el rendimiento es crucial en este momento. De todos modos, no podemos hacer mucho ya que el esquema de la base de datos parece estar equivocado. Se sentía bien desde la perspectiva orientada a objetos, pero parece ridículo desde la perspectiva relacional. Me pregunto: ¿Cómo ha sucedido esto? Los desarrolladores nos dicen que cambiar la estructura de las entidades va a ser un gran esfuerzo, por lo que no podemos permitirnos eso. Recuerdo que en el proyecto anterior era un desastre, pero nunca llegamos a un punto tan crítico. Pudimos escribir una aplicación completamente diferente para trabajar con los datos. Ahora, es arriesgado modificar esas tablas generadas ya que es muy difícil asegurarse de que el modelo de entidad siempre se comporte correctamente. ¡Y esto no es ni siquiera la peor parte! Para aumentar el rendimiento, tenemos que resolver no solo los problemas de la base de datos, sino también los problemas de toda la capa entre nuestra base de datos y la aplicación. ¡Es abrumador! Tenemos estos nuevos tipos, ya sabes, consultores. Están tratando de extraer datos, ponerlos en algún otro almacenamiento y luego realizar cálculos desde el exterior. ¡Todo está tomando demasiado tiempo!

juan- no se que decir

Mónica - Ves a John; No quiero culparte. Elegí Hibernate para resolver todos estos problemas, pero ahora he aprendido que no es una panacea. El daño ya está hecho y es irreversible. En realidad, me gustaría preguntarte algo: pasé los últimos cuatro años de mi carrera lidiando con cosas de Hibernate . Parece que no tengo futuro en mi empresa actual. ¿Me puedes ayudar?

Entonces, ¿cuál es la lección aprendida?

Hoy dia

John - Oye, Peter, déjame presentarte a Monica.

Peter- ¡Hola, Mónica! Estamos construyendo nuestra nueva próxima gran cosa, ya sabes. ¡Va a ser enorme! ¡Queremos ser como Uber! ¿Sabes tal vez cómo la persistencia...

Mónica - ¡No hibernar !

Envolver

Mónica es una experta en Hibernate . Sin embargo, Hibernate en este caso fue una decisión equivocada. En el momento en que descubrió que su solución se convirtió en un problema mayor que el original, fue la mayor amenaza para todo el proyecto.

Los datos son el objetivo central de la aplicación y, nos guste o no, afectan a toda la arquitectura. Como aprendimos de la historia, no use Hibernate solo porque su aplicación Java está usando una base de datos o por prueba social. Elija una solución que abarque la flexibilidad. Hay muchas opciones para contenedores JDBC robustos, como JdbcTemplate o Fluent JDBC Wrapper. Alternativamente, existen otras soluciones poderosas, como jOOQ.