luni, 1 iunie 2009

Hibernate session and web application

În acest articol prezint modul în care se poate evita în totalitate folosirea fetch type-ului EAGER în aplicații web. Există un mod recomandat pentru a deschide o sesiune hibernate în aplicații web: acela este de a folosi un filtru care să deschidă sesiunea și să o facă disponibilă pe request. În acest fel orice entitate are nevoie de o sesiune de hibernate validă o folosește pe cea de pe request. De asemenea, în cazul instanțierilor LAZY pentru colecții, în momentul în care accesați un element al colecției nu veți primi eroare session closed. Primul cod prezentat este cel pentru filtrul care deschide o sesiune hibernate.

public class ManageConexiune implements Filter {

private FilterConfig filterConfig;

public void destroy() {}

public void init(FilterConfig fConfig) {

this.filterConfig = fConfig;

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {

Object obj = request.getAttribute("OPENED_CONNECTION");

Session ses = null;

if(obj != null) {

ses = (Session)obj;

try {

ses.close();

}

catch(HibernateException ex) {

ex.printStackTrace(); //just print the stack trace into log files

}

}

ses = HibernateSingleton.getInstance().openSession();

request.setAttribute("OPENED_CONNECTION", ses);

chain.doFilter(request, response);

}

}


Obs: Clasa HibernateSingleton pune la dispoziție două metode statice: una din ele este getInstance care returneaza un SessionFactory. Cea de a doua metodă statică nu face altceva decât să returneze sesiunea deschisă de pe request.


public class HibernateSingleton {

  private static SessionFactory sessionFactory;

   

  static

  {

  sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();

  }

   

  public static SessionFactory getInstance()

  {

  return sessionFactory;

  }

  public static Session getRequestSession() {

  return (Session)Contexts.getRequest().getAttribute("OPENED_CONNECTION");

  }

}


Astfel, ori de câte ori aveți nevoie de o sesiune validă invocați HibernateSingleton.getRequestSession. Utilizând maniera deschisă aici veți evita multe erori de genul Can't open connection sau Session closed. De asemenea, veți simți o îmbunătățire a performanțelor site-ului și veți obține timpi de acces mai buni.

Un comentariu:

  1. Mda... si unde demonstrezi ca nu mai trebuie EAGER ?

    Cu solutia ta vei evita exceptiile generate de accesarea unei asocieri neinitializate a unui obiect in modul detached (in terminologia hibernate), dar Eager fetching este folosit pt cu totul altceva decat pt evitarea exceptiilor, si anume pentru optimizarea accesului la baza de date. Spre exemplu poti sa eviti problema celor n+1 selecturi folosind eager fetching. In loc de n+1 selecturi, vei avea doar unul. Asta inseamna eager fetching, deci nu cred ca ar fi bine sa nu mai o folosim in aplicatiile web

    RăspundețiȘtergere