I have a large amount of rows in the database from which I need to create an XML document. I am using hibernate 3. The basic list() method in Criteria and Query interfaces looks dangerous: I quess it pretty much has to read all the records into memory even if I only iterate over them. Or is there some lazy loading magic? If not, I seem to have two options left: using scroll() or iterate() from Query (scroll is also present in Criteria). iterate doesn't look all that great either if I want to have minimal SQL roundtrips: "The first SQL query returns identifiers only". So am I right, do I have to use scroll() for this?
+1
A:
Use the setMaxResults() method on 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
Paul Croarkin
2008-11-16 17:20:16
What I want to do is have all the results out in transactional fashion. I gather that you mean I should build the whole big resultset from parts. Can I use these to "stitch" my consistent, big resultset together so that I really get a snapshot from a certain point of time.
auramo
2008-11-16 19:16:23
I'm not sure what you mean by "have all the results out in a transactional fashion".
Paul Croarkin
2008-11-16 19:23:54
What I mean is that my resultset is a snapshot, no writes/deletes which happen in between from other clients will affect that.
auramo
2008-11-17 09:02:54
A:
Also, have a look at batch fetching Section 19.1.4 and 19.1.5 should do. http://www.hibernate.org/hib_docs/v3/reference/en-US/html_single/#queryhql-joins-forms
questzen
2008-11-16 17:33:10
Do you know whether those batch-queries (e.g. 10, 10 and 5 cats in the example) end up all in the list (if I query the table with list() in memory while I iterate through it? Or can hibernate unload the first batch when I proceed to the next batch (e.g. the next 10 cats after the first 10 cats).
auramo
2008-11-16 19:22:56
A:
This is what I'm planning on doing: Create a temporary table with the object IDs of all the rows I need to export:
Insert into BatchTable (ID, Seq) Select (O.ID, Sequence.Next)
From MyObject O Where ...
In small units of work load in the objects:
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();
}
Justin
2009-08-12 22:38:15
+1
A:
If you don't need to mark the objects off as procesed, you can simply use scroll() and evict the objects from the session as you are done with them.
Justin
2009-08-18 21:49:26