11

What exactly is the difference between using Query.list() and Query.iterator()?

Is there is any performance enhancement in using either. I mean that is any of them implementing lazy loading ?

Or is Query.iterator() ultimately same as query.list().iterate()

Also why is there no Criteria.iterator() only Criteria.list()

Avinash R
  • 3,101
  • 1
  • 27
  • 47

4 Answers4

16

Query.list(): Executes 1 SQL query and loads the entire data. Even if the records are present in cache a fresh SQL query is executed to load the records from the database.

List<Employee> list1 = session.createQuery("from Employee").list(); // SELECT *FROM EMP
for (Employee e : list1) {
    System.out.println(e);
}
List<Employee> list2 = session.createQuery("from Employee").list(); // SELECT *FROM EMP
for (Employee e : list2) {
    System.out.println(e);
}

Query.iterate(): Executes 1+N SQL queries. The first query only returns the identifier of all the records and when the returned iterator is iterated then each time a separate SQL query is executed that contains a WHERE clause like “WHERE id=N”. If the records are present in cache then the first query is executed and the rest N queries are not executed and records are obtained from cache.

Iterator<Employee> iterator1 = session.createQuery("from Employee").iterate(); // SELECT EMP_ID FROM EMP
while(iterator1.hasNext()) {
    System.out.println(iterator1.next()); // SELECT * FROM EMP WHERE EMP_ID=?
}
Iterator<Employee> iterator2 = session.createQuery("from Employee").iterate(); // SELECT EMP_ID FROM EMP
while (iterator2.hasNext()) {
    System.out.println(iterator2.next()); // From cache, no SQL
}
Amitabha Roy
  • 769
  • 5
  • 8
7

If instances are already in the session (primary-level cache) or second-level cache iterate() will give better performance.

If they are not already cached, iterate() will be slower than list() and might require many database hits for a simple query.

timrau
  • 22,578
  • 4
  • 51
  • 64
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • 1
    so what about the Criteria.iterator()?, why isn't it there? – Avinash R Feb 19 '13 at 13:11
  • 2
    The problem, is that it makes difficult to change from criteria to query without changing the interface, as data types returned are different. Adding Iterator support to Criteria, should be as easy as wrapping ScrollableResult in an Iterator implementation, and it would allow to return an Iterator with both HQL and Criteria. – Suresh Atta Feb 19 '13 at 13:24
  • Hi suresh i think for iterate it looks for the second level cache only and not the first level cache. – unknown Oct 30 '14 at 11:23
3

The javadoc says:

Return the query results as an Iterator. If the query contains multiple results pre row, the results are returned in an instance of Object[].

Entities returned as results are initialized on demand. The first SQL query returns identifiers only.

(emphasis mine)

Community
  • 1
  • 1
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1
+----------------------------------------------+-----------------------------------------------+
|                    list()                    |                   iterate()                   |
+----------------------------------------------+-----------------------------------------------+
| Return type is List                          | Return type is Iterate                        |
| All records loads at single database request | For each record, one database hit is made     |
| This is faster if cache is not available     | This is very slower if cache is not available |
| Eager loading                                | Lazy loading                                  |
+----------------------------------------------+-----------------------------------------------+  

For list():

Query query = session.createQuery("from Employee");
List list = query.list(); // SELECT * FROM EMP
Iterator iterator = list.iterator();
while(iterator.hasNext()){
}  

For iterate():

Query query = session.createQuery("from Employee");
Iterator iterator = query.iterate(); // SELECT * FROM EMP
while(iterator.hasNext()){
    // SELECT * FROM EMP WHERE EMP_ID=?
}
Premraj
  • 72,055
  • 26
  • 237
  • 180