Eficiencia Ejecutando Querys Con Hibernate

De Dos Ideas.
Revisión del 14:45 16 abr 2009 de Acandal (discusión | contribuciones) (Página creada con ' Hibernate provee varias formas de ejecutar un mismo Query HQL, devolviendo los resultados de distintas maneras. La interfaz que se utiliza para la ejecución de queries es pr...')
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Saltar a: navegación, buscar

Hibernate provee varias formas de ejecutar un mismo Query HQL, devolviendo los resultados de distintas maneras. La interfaz

que se utiliza para la ejecución de queries es precisamente org.hibernate.Query que provee 3 metodos para obtener los

resultados de un Query: list(), iterate() y scroll(). Se analizarán los dos primeros en cuanto a eficiencia en nuestras

aplicaciones.

Query.list()

El método Query.list() devuelve en una colección todos los resultados del Query. Es decir, en la colección se encuentran

instanciadas todas las entidades que corresponden al resultado de la ejecución del HQL, por lo tanto el ResultSet subyacente

de la conexión JDBC se cierra ya que no se necesita más.

Notar que esta alternativa realiza una única comunicación con la base de datos en donde se traen todos los resultados y requiere que haya memoria suficiente para almacenar todos los objetos resultantes del query. Si la cantidad de resultados es extensa, el delay del acceso a la base será notorio.

Ejemplo:

Query q = session.createQuery("from Auto auto where auto.aniocreacion < 1985 "); List autos = q.list();


Query.iterate()

El método Query.iterate() devuelve un iterador java.util.Iterator para iterar los resultados del query. En este caso, las entidades se instancian "a demanda", es decir, con cada llamada al método Iterator.next() que devolverá la

entidad de la posición actual del iterador.

Para resolver esto, Hibernate ejecuta el query obteniendo sólo los ids de las entidades, y en cada llamada al método next()

ejecuta la consulta propia para obtener la entidad completa. Esto se traduce en una mayor cantidad de accesos a la base de

datos, resultando en un mayor tiempo de procesamiento total. La ventaja de este método es que no se requiere que todas las

entidades estén cargadas en memoria simultáneamente, consumiendo memoria innecesariamente.

Para optimizar la obtención de entidades haciendo que no se realice un acceso a la base por cada llamada al metodo

Iterator.next(), se puede fijar la cantidad de resultados a traer en cada acceso o "fetch". Esto se configura llamando al

método Query.setFetchSize() antes de la ejecución de la consulta.


Ejemplo:

Query q = session.createQuery("from Auto auto where auto.aniocreacion < 1985 "); q.setFetchSize(10); // se obtendrán 10 resultados en cada acceso a la base. Iterator iter = q.iterate(); while ( iter.hasNext() ) {

   Auto auto = (Auto) iter.next();  // fetch the object
   ...
   

}

Debe tenerse particular cuidado en que no se cierre la sesión de hibernate mientras se utiliza el iterador, de lo contrario

no se podrán obtener los resultados subsiguientes de la base de datos.


Conclusión

Para los casos en que se deban tener acceso simultáneo a todas las entidades resultantes de un Query, el método Query.list()

cumplirá con los requisitos, teniendo en cuenta que todos los resultados esperados ocuparán espacio en memoria.

Si lo que se necesita es realizar una operación con cada entidad y luego esa entidad no se utilizará más, el método

Query.iterate() se ajusta mejor ya que permite limitar (con Query.setFetchSize() ) la cantidad de resultados que se tienen en

memoria y no consumir recursos innecesariamente, haciendo que la aplicación sea más eficiente y menos propensa a fallos por

falta de memoria en casos potenciales de muchos resultados en un query.


Vea También

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Query.html Hibernate Query Interface http://www.hibernate.org/hib_docs/reference/en/html/objectstate-querying.html Hibernate Queriying http://static.springframework.org/spring/docs/1.1.5/api/org/springframework/orm/hibernate/HibernateTemplate.html Querys con Spring HibernateTemplate http://articles.techrepublic.com.com/5100-10878_11-1046675.html Deciding between iterators and lists for returned values in Java http://java.sun.com/j2se/1.4.2/docs/api/java/sql/ResultSet.html Interface java.sql.ResultSet