martes, 2 de octubre de 2007

Hibernate + Struts se cuelga

OK, no se a que se deba pero me pasa que cuando estas utilizando la instanciación de los objetos Hibernate desde Spring y usando Struts de vez en cuando se le da la gana pararse y no funciona... No se por que y la verdad creo que es algo que no deberia suceder. Bueno, en el modelo que se ha planteado en el blog... y si no esta en uno de los materiales de curso... la solución que he implementado es algo mas o menos asi:


  1. Crear un singleton HFactory




  2. public class HFactory {
    private static HFactory instance;
    private SessionFactory sf;
    //Constante de el directorio donde estan los mapeos
    private static final String DONDE = "mx.edu.itsur.ds.mapping";

    //Constructor privado para evitar instanciacion
    private HFactory() {
    //Configuramos entonces el sf
    Configuration cfg = new Configuration();

    /*Mi vida: Capitulo 1...
    Hace mucho tiempo, en un lugar muy, muy lejano, nacio un lindo niño
    que vino a iluminar con su nacimiento a este triste y aburrido mundo */
    try {
    //Usamos las librerias de spring para acceder a los recursos locales
    Resource r = new ClassPathResource(DONDE);
    File f = r.getFile();
    File[] fs = f.listFiles();

    //Checamos cuales tienen extension XML y los agregamos a la configuracion
    for(int i = 0; i < fs.length; i++) {
    String nombre = fs[i].getName();
    if(nombre.indexOf(".xml") == nombre.length - 4)
    cfg.addResource(CODE + "/" + nombre);
    }

    //Obtenemos nuestro nuevo SF
    this.sf = cfg.buildSessionFactory();
    } catch(Exception e) { e.printStackTrace(); }
    }

    //Singleton
    public static HFactory getInstance() {
    if(instance == null)
    instance = new HFactory();
    return instance;
    }

    //Devolvemos un SF para otros objetos
    public static SessionFactory getSF() {
    return getInstance().sf;
    }
    }


  3. Quitar las dependencias del SF de spring



  4. Después de esto vamos a eliminar la linea que incluye al hibernate.xml
    del archivo applicationContext.xml; eso obviamente va a causar un buen de problemas
    con todos los DAOS y la aplicación se va a parar si estaba funcionando. En cada uno de los archivos que incluye el applicationContext.xml vamos a quitar todas
    las referencias al objeto sf que se define en el archivo hibernate.xml



  5. Instanciar el SessionFactory cuando se ocupe



  6. OK, ahora todo dejo de funcionar porque los objetos DAO no tienen un SF para funcionar, vamos a hacer uso de la hermosa herencia para crear esta dependencia desde el momento en que se crea el objeto DAO. Supongamos que tenemos una clase HibernateDAO que es la base de todos los daos...




    public class HibernateDAO implements BasicDAO {
    //Vamos a cambiar solamente el constructor

    public HibernateDAO(String clase) {
    //Esta linea antes de las operaciones normales de creacion
    sf = HFactory.getSF();

    //Y todo lo que ya tenia el DAO
    }
    }




Con esta solución el dependency injection se realiza desde HibernateDAO y todas las clases que extiendan de el tienen la vida resuelta. Con esto ya mi servidor no se ha parado.