¡No uses Stored Procedures!

Todo es bueno y malo según lo utilices, pero hay ciertas cosas, que es mas fácil, que caiga en no utilizarlas bien.

-Javier Garzas.

Este es un articulo algo largo que carece de ejemplos técnicos o prácticos pero por el contexto de mi historia se entenderá de el por que nunca los he usado y tampoco necesitado, espero seguir así.

Cuando inicie en el mundo de la programación entre en un curso del CEDIS(Centro para el Desarrollo de la Industria del Software), en el cual al finalizar me consiguieron una entrevista de trabajo para entrar a una consultora y desde allí no paré de trabajar.

En el curso nos hicieron hincapié entre la diferencia de Java y Java EE, como debe ser la arquitectura de una aplicación Java EE, algunos conceptos como WAR, EJB, JSP, JSF, ORM, JPA, HTML, CSS, Javascript y SQL.

Ya dentro de la realización de los requerimientos vimos como mapear, insertar,consultar, actualizar y borrar registros de la base de datos con el Entity Manager.

Modelamos algunas bases de datos relacionales y nos dimos cuenta de la importancia de las relaciones y que cuando llegamos a algún lugar sin salida, apegarnos a las reglas básicas de normalización, simple, pero efectivo.

Al llegar a mi primer trabajo mis mentores, tenían muy buena experiencia y me reafirmaron con practica y fundamentos técnicos lo que había aprendido con la teoría, ademas de algunas otras cosas, me hablaban de JPQL , de por que aveces era necesario utilizar el ORM en lugar de JPA y por que las consultas nativas eran malvadas.

Nunca ejecute una consulta nativa con JDBC creando conexiones a la base de datos de forma programática, siempre obtenía la conexión de un JNDI en el DataSource del servidor y hacia la consulta con JPQL o HQL, hacerlo con JDBC eran muchos problemas y sumarle que es una consulta nativa todavía mas.

Cuando decidí cambiarme de trabajo fui a varias entrevistas, muchas de ellas con tecnologías raras y mezclaban cosas que no deberían ser, algunas consultoras ofrecían muy buenos sueldos, mixtos por supuesto, pero requerían que trabajar con PHP, .Net, PL/SQL, Ruby, Node, Java etc.

Rechace el trabajo y les hice la observación de que eso no era hacer software de calidad, les traería muchos problemas, en su defensa, ellos alegaron trabajar para el gobierno, una razón mas para hablar de política, el gobierno decidía con que... y como..., para mi el usuario/cliente no manda, solo da la dirección, nosotros somos los expertos o deberíamos ser.

Antes de cambiarme contrataron a mi reemplazo y comencé a explicarle en que estaba y que era lo que seguía, las consultas, que versión de Hibernate teníamos, le enseñe el HTML y como utilizando Bootstrap podías maquetar sin una linea de CSS.

No se si realmente me estaba poniendo atención, pero recuerdo muy bien su pregunta.

¿ Oye y donde están los Stored Procedures ?

Yo, realmente no supe que responder y dije , ¿ los que ? , el me respondió muy serio, si , ¿Donde están los Stored ? , yo no sabia que era eso y recurrí, como buen aprendiz, a mi mentor, el cual contesto que nosotros no utilizábamos Stored Procedures.

El me pregunto que como hacíamos para ejecutar las consultas a la base de datos y trate de explicarle en 2 horas que era un ORM, JPQL, las ventajas de su uso, etc.

Me di cuenta de que aunque trabajó con Java, simplemente no sabia que era Java EE.

Fue la primera vez que escuche esa pregunta y después en otras entrevistas de trabajo la volví a escuchar, muchas veces, mas de las que me gustaría.

Quizá con otros lenguajes o plataformas en el desarrollo de software sea valido, en Java EE no.

Después platique con muchas personas y la mayoría defendían a capa y espada el uso de los Stored Procedures y por que los ORM's son 200 mili-segundos mas lentos en una consulta.

En ese punto se me ocurrió una pregunta en forma de analogía muy buena que va así.

Un carro irá mas rápido si le quitas los asientos, vidrios y las puertas, ¿Por que no se los quitas?

Lo mismo pasa con el JDBC, una consulta tardara mucho menos ejecutándola con JDBC que con el ORM, pero pierdes la transaccionalidad, el mapeo automático de objetos, el poder agregar un cache, la potabilidad, comprobación de las tablas, los validadores JSR 303, estar expuesto a SQL Injection , entre otras cosas.

La mayoría responde defendiendo que pueden hacer un cache manual, que no necesitan el @Transactional, nunca cambiarán la base de datos y que para que perder tiempo en convertir la consulta a un objeto si pueden retornar un Array de Strings, ¡Válgame Dios!.

Al trabajar con JDBC en solitario, se vuelve un calvario, no existe un orden, la lógica esta en la base de datos con los Stored y se comienza a hacer pequeños pecadillos, como:

No usar los tipos correctos para algunos campos, un ejemplo son las fechas.

Se comienza a evitar el uso de llaves foráneas, es decir si se escribe el campo como tal que hace referencia a X tabla, pero no se crea la llave foránea a la tabla X.

La actualización de registros se vuelve en extremo tediosa y se prefiere borrar el registro y crear uno nuevo, también por lo mismo se evitan las llaves foráneas.

Lo anterior crea un mal modelo de base de datos, el cual no soporta cambios, ya que si borras un campo no sabes a que Stored Procedure le puedes pegar, pues estos solamente mandaran el error en tiempo de ejecución.

A mi no me extraña que no se le tomara importancia a esta funcionalidad de la base de datos hasta la versión de JPA 2.1, pues para que quieres algo que no puedes ver directamente en el proyecto y que puedes hacer lo mismo con una consulta nativa.

Algunas personas me hacen la mención de como le va a hacer si varias aplicaciones tienen que ejecutar el mismo Stored y les contesto que no es necesario.

Solo hay que exponerlo mediante algún servicio y la base de datos debe estar conectada a un único middleware que la controle, de otra forma no será posible tener un cache, utilizar Hibernate Search o alguna otra implementación de Lucene, obvio el Stored se va y en su lugar lo reemplazo con un bonito JPQL, Criteria y nativo en otros casos.

¿ Que tan maduro son los ORM's y JPA ?, tan maduros como los cerros, en Wikipedia nos dice que la primera versión de JPA es del 11 Mayo del 2006, la primera versión de Hibernate, mi ORM de cabecera es del 30 de noviembre del 2001.

En toda mi experiencia laboral, nunca necesite un Stored Procedure, para nada, quizá por que siempre trabajo con Java EE , en Nodejs siempre utilice Mongo DB, pero parece ser que ya existe un ORM que empieza a calar llamado Waterline.

Desconozco si en otros países esto sea algo común, pero en México si lo es, solo vayan a la pagina de Java México y encontrarán ejemplos muy pintorescos de todo lo que estoy escribiendo, sonare muy alarmista en esto pero es horrible darle mantenimiento a proyectos así, no se lo deseo a nadie.

Quiero poner mi granito de arena para que el día de mañana que alguien le toque modificar algún proyecto mio no se encuentre en las situaciones por las que yo pase, espero poder dejarle un proyecto lleno de pruebas unitarias, pruebas e2e , indicadores de calidad mínima,sin código repetido y la infraestructura para comenzar con las DevOps.

No es mi intención dañar a nadie, ya que existen plataformas en las cuales los Stored Procedures encajen perfectamente, pero en Java EE ¡NO! , cuando encuentre el caso técnico valido, actualizare este articulo, pues por ahora lo desconozco completamente.

Si necesitan ayuda u orientación de esto, pueden leer mis artículos anteriores sobre Spring, escribir en los comentarios o mandarme un correo.

Por fin me desahogue xD

Fuentes :

https://en.wikipedia.org/wiki/Hibernate_(framework)

https://forum.hibernate.org/viewtopic.php?f=1&t=955560&view=next