Como implementar o Jakarta Commons Pool para uma Factory de Sessão do Hibernate

 

Autor: Ricardo Malnati Rosa Lima

 

Referência:

Projeto: http://jakarta.apache.org/commons/pool

Exemplos: http://jakarta.apache.org/commons/pool/examples.html

Downlods http://jakarta.apache.org/commons/pool/downloads.html

 

O Pool é uma implementação de PoolableObjectFactory, responsável por manter objetos em memória com a mesma referência de quando foram instânciados, dando a possibilidade de reutilizá-los quando o programador invocar os métodos da Interface PoolableObjectFactory. Imagine que você pode precisar de uma mesma instância de objeto para diversas situações; porém, precise limitar o número de instâncias desse objeto.

 

Mesmo sabendo que existem muitas outras formas de fazer controle de Session do Hibernate, um bom exemplo da implementação de um Pool é utilizá-lo para criá-las.

 

Para que esse tudo funcione corretamente, todos as instâncias de Session devem vir através do Pool, pois o Pool controla o número de sessões abertas; por tanto, após utilizar a Session, vinda através do método leave(), o programador deve devolver a mesma Session para o Pool invocando o método back(session).

 

Segue abaixo o código fonte de uma implementação do PoolableObjectFactory, o XML que contém os parâmetros da instancia de ObjectPoolFactory e logo abaixo uma classe que utiliza o Pool.

 

//---------------------------------------------------------- SessionPoolFactory.java

import org.apache.commons.pool.ObjectPool;

import org.apache.commons.pool.PoolableObjectFactory;

import org.apache.commons.pool.impl.GenericObjectPool;

import org.hibernate.FlushMode;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

 

public class SessionPoolFactory implements PoolableObjectFactory {

 

  private static final int  MAX_ACTIVE = 50;

  private static ObjectPool pool;

   

  static {

    try {

      pool = new GenericObjectPool(new SessionPoolFactory(), MAX_ACTIVE);

    } catch (Exception e) {

      e.printStackTrace();

      IllegalStateException exc = new IllegalStateException();

      exc.initCause(e);

      throw exc;

    } catch (Error e) {

      e.printStackTrace();

    }

  }

 

  public static Session leave() {

    Session session = null;

    try {

      session = (Session) pool.borrowObject();

      session.setFlushMode(FlushMode.AUTO);

    } catch (Exception e) {

      e.printStackTrace();

    }

    return session;

  }

 

  public static void back(Session session) {

    try {

      pool.returnObject(session);

    } catch (Exception e) {

      e.printStackTrace();

    }

  }

 

//-- implementacao do PoolableObjectFactory -------------------------------------

/*Cria objetos do tipo Session*/                

public Object makeObject() throws Exception {

               SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

               Session session = sessionFactory.openSession();

               return session;

}

/*Destroi objeto do tipo Session passado por parametro*/

public void destroyObject(Object arg0) throws Exception {

               Session session = (Session)arg0;

               session.close();

}

/*Valida objetos do tipo Session passado pelo parâmetro, no caso estou verificando se a sessão esta aberta*/

public boolean validateObject(Object arg0) {

               Session session = (Session)arg0;

               return ( session!=null && session.isOpen() );

}

/*Cria objetos do tipo Session*/

public void activateObject(Object arg0) throws Exception {

               Session session = (Session)arg0;

               if ( session!=null && !session.isOpen() ){

                    session.reconnect();

}

}

/*Não vi necessidade de implementar esse metodo*/

public void passivateObject(Object arg0) throws Exception {}

}

Código 1.nSessionPoolFactory.java

//--------------------------------------- HibernateQuery.java

import java.util.List;

import org.hibernate.Query;

import org.hibernate.Session;

 

public class HibernateQuery {

 

  public List search(String hql) {

    List result = null;

    Session session = null;

    try {

      session = SessionPoolFactory.leave();

      Query query = session.createQuery(hql);

      result = query.list();

    } catch (Exception e) {

      System.out.println(" ---->Excessão na query: <<" + hql + ">>");

      e.printStackTrace();

    } catch (Error e) {

      System.out.println(" ---->Erro na query: <<" + hql + ">>");

      e.printStackTrace();

    } finally {

      SessionPoolFactory .back(session);

    }

    return result;

  }

public static void main(String[] args) {

    String hql = "";

    HibernateQuery hq = new HibernateQuery();

    List<String> ls = hq.search(hql);

    for (String str : ls) {

      System.out.println(str);

    }

  }

}

Código 3.n – HibernateQuery.java

 

Sobre o autor


Ricardo Malnati Rosa Lima é desenvolvedor Java desde 2002, reside em Brasília desde 2003 onde trabalha com aplicações Java para web. Atualmente colabora como líder de um projeto de CRM (Customer Relationship Management) para uma empresa de Call Center.

 

Artigo editado pela ultima vez em 19 de janeiro de 2007, Brasília-DF.