2008-11-16 14 views
6

Tengo una gran cantidad de filas en la base de datos desde la cual necesito crear un documento XML. Estoy usando hibernate 3. El método de la lista básica() en Criteria y las interfaces de consulta parece peligroso: lo que más me preocupa es que lea todos los registros en la memoria, incluso si solo iterar sobre ellos. ¿O hay alguna magia de carga floja? Si no, parece que me quedan dos opciones: usar scroll() o iterate() desde Query (scroll también está presente en Criteria). iterar no se ve muy bien si quiero tener un mínimo de ida y vuelta SQL: "La primera consulta SQL solo devuelve identificadores". Así que estoy en lo cierto, ¿tengo que usar scroll() para esto?Hibernar: evitar leer todos los registros en la memoria de una vez

+0

Esto también se aplicó a NHibernate :) –

Respuesta

1

Use el método setMaxResults() en Criteria.

Criteria crit = sess.createCriteria(Cat.class); 
crit.setMaxResults(maxResults); 
crit.setFirstResult(firstResultIndex); 
List cats = crit.list(); 

http://hibernate.org/hib_docs/v3/reference/en/html/querycriteria.html

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html

+0

Lo que quiero hacer es tener todos los resultados en forma transaccional. Entiendo que quieres decir que debería construir todo el gran conjunto de resultados de partes. ¿Puedo usar estos para "unir" mis conjuntos de resultados consistentes y grandes para que realmente obtenga una instantánea desde un cierto punto de tiempo. – auramo

+0

No estoy seguro de lo que quiere decir con "tener todos los resultados de forma transaccional". –

+0

Lo que quiero decir es que mi conjunto de resultados es una instantánea, ninguna escritura/eliminación que ocurra entre otros clientes afectará eso. – auramo

-1

También, echar un vistazo a la recuperación en lotes Sección 19.1.4 y 19.1.5 debe hacer. http://www.hibernate.org/hib_docs/v3/reference/en-US/html_single/#queryhql-joins-forms

+0

¿Sabe si esas consultas por lotes (por ejemplo, 10, 10 y 5 gatos en el ejemplo) terminan todas en la lista (si consulto la tabla con list() en la memoria mientras la recorro? O puede hibernar la descarga primer lote cuando procedo al siguiente lote (por ejemplo, los próximos 10 gatos después de los primeros 10 gatos). – auramo

0

Esto es lo que estoy pensando en hacer: Crear una tabla temporal con los ID de objetos de todas las filas que necesito para exportar:

Insert into BatchTable (ID, Seq) Select (O.ID, Sequence.Next) 
From MyObject O Where ... 

En pequeñas unidades de carga de trabajo en los objetos :

Select Min(B.Seq), Max(B.Seq) From BatchTable; 

for (batch = minBatch; batch <= maxBatch; batch += size) { 
beginTransaction(); 
results = query("Select O From MyObject O, BatchTable B 
        Where O.ID = B.ID and (? <= B.Seq AND B.Seq < ?)"); 

exportXML(results); 
for (MyObject O : results) { 
    O.setProcessed(True); 
    O.update(); 
} 
commit(); 
} 
1

Si no es necesario marcar los objetos fuera como procesed, sólo tiene que utilizar de desplazamiento() y desalojar a los objetos de la sesión como haya terminado con ellos.

2

Try usando desplazamiento(), en relación con esto:

http://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/StatelessSession.html

A API orientada comando-para realizar operaciones a granel contra una base de datos.

Una sesión sin estado no implementa una memoria caché de primer nivel ni interactúa con ninguna memoria caché de segundo nivel, ni implementa escritura transaccional retrasada o comprobación sucia automática, ni las operaciones se conectan en cascada a las instancias asociadas. Las colecciones son ignoradas por una sesión sin estado. Las operaciones realizadas a través de una sesión sin estado omiten el modelo de eventos e interceptores de Hibernate. Las sesiones sin estado son vulnerables a los efectos de alias de datos, debido a la falta de un caché de primer nivel.

Para ciertos tipos de transacciones, una sesión sin estado puede funcionar un poco más rápido que una sesión con estado.

Cuestiones relacionadas