Sesiones y transacciones en hibernate: el “problema” de tirar pa’arriba

Sigo con mi serie de posts sobre el desarrollo de OCAS. En este intentaré describir mi problema, y en el próximo lo que creo que va a ser la resolución de esta apasionante serie :-P.

El objetivo que nos hemos marcado en OCAS es proporcionar una capa de servicios que ayuden a la programación en tareas típicas a los que nos enfrentamos proyecto a proyecto, abstrayendo la complejidad de las librerías a los programadores. De la misma forma nuestra idea es dar diferentes implementaciones a esos servicios para que el desarrollador elija la que más le guste. En breve el wiki contendrá más información.
En estos momentos me encuentro desarrollando la implementación del servicio de workflows con la librería open source JBPM, que a su vez usa como mecanismo de persistencia hibernate. Y es aqui donde empezó la paja mental causante de esta serie de posts ;-)

Veamos, jbpm ofrece en su API unas “sesiones” jbpm, que no son más que un wrapper de las sesiones hibernate. A partir de una sesión jbpm se obtienen unos objetos sesión (GraphSession, TaskMgmtSession…), que yo calificaría como una especie de DAO’s (para entendernos ;-)) para trabajar (CRUD) con determinados aspectos de un proceso. El tema es que en jbpm hacen aaaampliooooo uso del lazy loading (las variables de un proceso son lazy por ejemplo). Hasta aquí puedo leer ;-), que me reservo un post sobre jbpm cuando lo tenga acabado.

Y aquí es donde empezamos a chocar con OCAS: nuestra pretensión es facilitar la vida al programador, no decirle que tiene que aprender hibernate para usar un servicio de workflows, y que tiene que tener claro que es una sesión y que es una transacción en hibernate. Y aquí es donde me parece que pecan algunas librerías que usan hibernate, simplemente transportan la interfaz de hibernate hacia arriba y le cuentan al programador que se mire la documentación. Por ejemplo, en jbpm hace falta conocer hibernate y su manejo de transacción/sesión y los patrones involucrados (ver post anterior) para entender porqué narices sale esa LazyInitializationException cuando pido las variables de un proceso fuera de la sesión jbpm que lo cargó. Para mí no tiene mucho sentido. Generalmente el código que usa hibernate adquiere una fuerte dependencia con él, lo cual tiene mucho sentido en DAO’s de acceso a BD, pero que deja de tenerlo cuando simplemente son librerías que hacen otra cosa además de usar hibernate ;-)


En mi implementación del servicio de OCAS he barajado varias soluciones para no molestar al usuario programador con los detalles de la implementación concreta en jbpm:

  • Modificar el código de jbpm para que determinadas relaciones no sean lazy: no sigue la filosofía de OCAS, en la que damos la implementación de nuestros servicios sin tocar el código fuente de las librerías.

  • Abrir y cerrar sesión en cada uno de los métodos de mi servicio de workflow. Por ejemplo así:

    public Map getVariables(){
            JbpmSession sesion = wfService.getJbpmSession();
            ProcessInstance process = sesion.getGraphSession().loadProcessInstance(processInstance.getId());
            Map result = process.getContextInstance().getVariables();
            wfService.closeJbpmSession(sesion);
            return result;
    }
    


    Buff, para mí apesta :-), se podría ver como una sesión por petición, pero el problema es que aquí no se trata la petición de un usuario web, sino de una llamada a un método de una librería, y en un request de una aplicación web puede haber varias decenas de llamadas a métodos. No se aprovecha el caché de primer nivel y además me obliga a cargar de nuevo el proceso desde la BD (porque antes lo cargué en una sesión jbpm/hibernate distinta) aunque ya lo tenga en memoria. Como ventaja lo único que puedo decir es que en la interfaz ofrecida del servicio al programador el no ve ni sesiones ni transacciones de hibernate, lo cual es mi objetivo.


  • Alguien podría decirme:

    Bueno pues cargate toda la info del proceso en memoria cuando se cargue el proceso y montate tu propia caché


    Puede ser, pero creo que he encontrado una solución mejor –> más productiva y eficiente (y sin escribir mucho más código)



  • Pero la solución (que desvelaré en un próximo post para mantener la intriga, y poder hacer los tests :-)) me vino el día de la hispanidad (como buen programador yo no tengo fiestas :-() mientras fregaba mi taza del café. Sólo os adelanto que tiene que ver con uno de los patrones que describen en hibernate, y que los usuarios de OCASWF sólo deben conocer el significado de una transacción (el general, el que conoce todo el mundo vaya). Os dejo con este atroz suspense, para que estos posts sirvan para ver las ventajas de usar OCAS y los sudores que nos cuestan.

    Salu2
    PD: Sólo espero que hibernate 3 haga todo lo que promete :-D

    0 Respuestas a “Sesiones y transacciones en hibernate: el “problema” de tirar pa’arriba”


    1. Ningún Comentario

    Añade un Comentario





    Close
    E-mail It