Maneras de integrar Struts2 con Hibernate

Struts2 sigue siendo uno de los frameworks web para java más populares. Lo del número 2 no está de más ya que ciertamente Struts2 y Struts a secas no tienen mucho que ver en cuanto a código. Aunque sí, formalmente los dos son frameworks MVC. Pero con Struts2 no es suficiente, ¿qué pasa con el acceso a los datos? Para facilitar la gestión de datos y ante todo poder centrarnos en el negocio y no andar por ejemplo cargando listas de objetos a mano de un resultset de jdbc disponemos de Hibernate, una pareja de baile ideal para Struts.

Hibernate logo
La sesión de Hibernate

Hibernate permite a nuestra aplicación abstraerse de la base de datos, hasta el punto siempre deseable en el que podemos cambiar la Base de datos tocando un fichero de configuración ajeno al código. Para que nuestra aplicación pueda acceder a los datos lo debe hacer a través de Hibernate y TODOS los accesos de Hibernate deben hacerse a través de una instancia de la clase Session. En una aplicación de consola por ejemplo, la clase java que pretenda acceder a los datos primero deberá conseguir una instancia de Session. Eso se suele hacer a través de una clase como esta

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
  
/**
 * provide Hibernate Session factory
 * @author Pello Xabier Altadill Izura
 * @greetz blue mug
 */
public class HibernateSession {
  
    private static final SessionFactory sessionFactory = buildSessionFactory();
    private static Session session;
  
    /**
     * Based on hibernate.cfg.xml configuration creates
     * a SessionFactory
     * @return the session factory
     */
    private static SessionFactory buildSessionFactory() {
            Configuration configuration = new Configuration();
            configuration.configure();
            ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        
            SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            return sessionFactory;
    }
  
    /**
     * this gives the desired session factory
     * @return hibernate Session Factory instance
     */
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    
    /**
     * gives the current Session
     * @return Hibernate Session
     */
    public static Session getSession () {
        if (null == session) {
                session = sessionFactory.openSession();
        }
        
        return session;
    }
}

Como se puede ver, lo que hace esta clase básicamente es cargar la configuración de Hibernate que se mete en el fichero hibernate.cfg.xml, y simplemente devuelve una instancia de Session. En la clase java que utilizar Hibernate accedemos y usamos la sesión de esta manera:

        /*
         * inserts a new seller in database
         * retrieves generated id and sets to seller instance
         * @param new seller
         */
        public void insert(Seller seller) {
            SessionFactory sessionFactory = HibernateSession.getSessionFactory();
            Session session = sessionFactory.openSession();
            session.beginTransaction();
         
            Integer id = (Integer) session.save(seller);
            seller.setId(id);
                 
            session.getTransaction().commit();
                 
            session.close();

        }

Hasta aquí todo ok, y en una aplicación de consola no hay problemas. Pero... ¿Cómo nos lo montamos en Struts2 para que nuestrar clases puedan sacar una instancia de Session de Hibernate? A continuación muestro tres maneras que se mencionan con frecuencia:

1. Usando el contexto de Servlet

Mykong, un habitual de las recetas J2EE indica que ya que no existe una forma oficial de integrar los dos frameworks, se pueden utilizar el contexto. ¿cuál es el contexto en Struts2? No estamos en consola, estamos en un contexto de Servlet. Así que lo que hace es una clase que genera la Session que implementa ServletContextListener, lo cual nos va a permitir conseguir la sesión en cualquier clase dentro de la aplicación Struts2. Se puede ver este ejemplo, y en concreto el funcionamiento se ve en las clases HibernateListener.java, CustomerAction.java y el listener que se configura en web.xml.

2. Usando una librería que lo integra por anotaciones

No es oficial pero existe un proyecto alojado en googlecode con el que se hace mucho más fácil. No tenemos más que instalar un fichero jar y con un par de anotaciones ya tenemos nuestro Factory y nuestra Session inyectados de forma automática:

...
import com.googlecode.s2hibernate.struts2.plugin.annotations.SessionTarget;
import com.googlecode.s2hibernate.struts2.plugin.annotations.TransactionTarget;

/**
* Implementation of UserDAO interface
* @author Pellop Altadill
* @greetz again and again
*/
public class UserDAOImpl implements UserDAO {
	
	@SessionTarget
	Session session;
	
	@TransactionTarget
	Transaction transaction;

	/**
	 * Used to save or update a user.
	 */
	@Override
	public void saveOrUpdateUser(User user) {
		try {
			session.saveOrUpdate(user);
		} catch (Exception e) {
			transaction.rollback();
			e.printStackTrace();
		}
	}
...

El único problema de esto es que esa librería no se ha actualizado desde 2010. Por tanto pese a que es la forma más simple de todas a la larga no ofrece muchas garantías.

3. Usar Hibernate como si nada

Bueno, otra opción es hacerlo de manera normal, como si estuvieramos en una aplicación de consola. En un post de otro clásico de los blogs J2EE, Viral Patel lo hace sin ningún tipo de medida especial. Para la Session crea una clase llamada HibernateUtil que es la que provee la Session. Utilizamos la clase previa de HibernateSession y la utilizamos en las clases DAO.

Proyecto en acción

Como muestra de esta integración en esta url tienes un proyecto de Eclipse listo desarrollado en Struts2 e Hibernate. Esta hecho desde 0 mano, sin Maven ni nada ya que hay gente a mi alrededor que con su Windows8 Maven le explota en la cara.

by Pello Altadill 11/17/2013 15:26:23 - 2165 hits

Arreglar e Iniciar el Oracle Enterprise Manager

Hablar de Oracle trae gratos recuerdos como la saga de IronMan y en especial la tercera entrega donde me transportaron a la nube de Oracle. El Enterprise Manager es un interfaz web con el que podemos gestionar la BD de Oracle: inicio/parada/blackout, ficheros, memoria, tareas, backups, usuarios, roles, y en definitiva todos los objetos que forman parte de los...

by Pello Altadill 11/10/2013 01:01:04 - 2131 hits

More »

Errores frecuentes en aplicaciones Struts2 con Eclipse y Tomcat

Introducción ¿Tu aplicación struts2 falla? ¿Ni si quiera arranca el tomcat o te está vomitando toda la stacktrace, toda la pila de llamadas erróneas por la consola? Antes de echarse a llorar, desesperarse, increpar al proyecto apache, al profesor debes asegurarte de unos mínimos: Tu proyecto no tiene errores de compilación Tus clases y jsps no tienen ni u...

by Pello Altadill 11/01/2013 01:44:50 - 2201 hits

More »

Interfaz Metro y Shortcuts en Windows 2012

Métodos abreviados Algunas cabezas pensantes le han dado una vuelta al interfaz gráfico de las últimas versiones de Windows. Dida lo que diga el Vaticano el purgatorio y el infierno existen y debe ser el destino para los creadores de Metro, que es como se llama el interfaz que aparece ahora en al pulsar la tecla windows. Aquí dejaré unas pautas para poder sobrevivir. Pese a que existen herramientas para quitarlo, para tener un inicio normal, etc… creo que no queda más remedio que acostu...

by Pello Altadill 08/31/2013 21:56:26 - 1760 hits

More »

Montar un laboratorio con máquinas virtuales en un host

Supongamos que queremos montar un laboratorio de máquinas virtuales para jugar con servidores y clientes. Varias máquinas virtuales que queremos: que sean visibles desde el host o equipo físico, que sean visibles entre ellas yque además puedan salir al exterior a través del equipo físico. Y es más, queremos que esas máquinas virtuales tengan IP fija ya que al ser servidores no queremos que las IPs bailen Y Vamos a suponer que tenem...

by Pello Altadill 08/31/2013 00:50:13 - 4884 hits

More »

Monitorizando un servidor Windows 2012

Otra cosa no sé pero si queremos monitorizar un servidor windows por herramientas no será. En comparación revisar un linux puede parecer una tarea sencilla porque el sistema es tan simple (todo son procesos y ficheros), que con unos comandos y una revisión del log nos hacemos una idea rápido. En el caso de windows, el sistema dispone de una monitorización gráfica de serie con todo lujo de detalles, cosa que para linux te obligaría a meter cosas tipo RRDtool, mrtg, etc... aunque obviamente, de nad...

by Pello Altadill 08/30/2013 00:55:09 - 795 hits

More »

Windows 2012 Server

Con eso de escribir acerca de linux y de hacer bromas sobre lo horrible que es windows es muy común que de forma inmediata te encasillen como talibán linuxero. Más aún si eres fiel a Debian y despotricas de Ubuntu por estar hecho para ser fácil. Pero lo cierto es que ante la típica pregunta de un comercial de ¿Qué sistema es mejor? o ¿qué lenguaje es mejor? para mí la re...

by Pello Altadill 08/28/2013 23:22:53 - 607 hits

More »

socket.io ...and websockets for all.

Otra de las novedades que trae HTML5 es la de los famosos websockets. El protocolo HTTP funciona de tal manera que no existe una conexión fija entre el cliente y el servidor; el navegador y el servidor se están continuamente lanzando piedras con mensajes, y a veces para simular que la conexión es permanente (una sesión) se acompaña de alguna marca como una cookie. Los websockets nos dan la posiblidad de establecer una conexión fija entre cliente y servidor como la que hay en un IRC o en los ...

by Pello Altadill 08/24/2013 23:11:46 - 677 hits

More »