Queryのiterate()とscroll()
なんかよくわかっていなかったので、試してみた。
iterate()
テストコード
public void testIterator() throws Exception { Session session = getSession(); Iterator<Employee> iterator = session.createQuery("from Employee e where e.id < 3").iterate(); try { while (iterator.hasNext()) { Employee e = iterator.next(); assertTrue(e instanceof HibernateProxy); assertTrue(session.contains(e)); e.getEmployeeName(); } } finally { Hibernate.close(iterator); } }
実行されるSQL
Hibernate: select employee0_.EMPLOYEE_ID as col_0_0_ from Employee employee0_ where employee0_.EMPLOYEE_ID<3 Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_2_0_, employee0_.EMPLOYEE_NO as EMPLOYEE2_2_0_, employee0_.EMPLOYEE_NAME as EMPLOYEE3_2_0_, employee0_.MANAGER_ID as MANAGER9_2_0_, employee0_.HIREDATE as HIREDATE2_0_, employee0_.SALARY as SALARY2_0_, employee0_.department_id as department8_2_0_, employee0_.ADDRESS_ID as ADDRESS7_2_0_, employee0_.VERSION as VERSION2_0_ from Employee employee0_ where employee0_.EMPLOYEE_ID=? Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_2_0_, employee0_.EMPLOYEE_NO as EMPLOYEE2_2_0_, employee0_.EMPLOYEE_NAME as EMPLOYEE3_2_0_, employee0_.MANAGER_ID as MANAGER9_2_0_, employee0_.HIREDATE as HIREDATE2_0_, employee0_.SALARY as SALARY2_0_, employee0_.department_id as department8_2_0_, employee0_.ADDRESS_ID as ADDRESS7_2_0_, employee0_.VERSION as VERSION2_0_ from Employee employee0_ where employee0_.EMPLOYEE_ID=?
- 最初にIDを取得するクエリを実行している。
- クライアントにはプロキシを返す。
- ID以外のプロパティにアクセスする段階で遅延ローディングされる。
- 毎回プロパティにアクセスするとN+1回のSELECTが実行されることになる。
- でも、すでにエンティティが永続コンテキストに入っていればSELECTは実行されない。
- 永続コンテキストに格納される。
- Iteratorの中で一番目のクエリのResultSetやPreparedStatementを持っているので自分でクローズしなきゃだめ。
scroll()
テストコード
public void testScroll() throws Exception { Session session = getSession(); ScrollableResults results = session.createQuery("from Employee e where e.id < 3").scroll(); try { while (results.next()) { Employee e = (Employee) results.get(0); assertFalse(e instanceof HibernateProxy); assertTrue(session.contains(e)); e.getEmployeeName(); } } finally { results.close(); } }
実行されるSQL
Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_2_, employee0_.EMPLOYEE_NO as EMPLOYEE2_2_, employee0_.EMPLOYEE_NAME as EMPLOYEE3_2_, employee0_.MANAGER_ID as MANAGER9_2_, employee0_.HIREDATE as HIREDATE2_, employee0_.SALARY as SALARY2_, employee0_.department_id as department8_2_, employee0_.ADDRESS_ID as ADDRESS7_2_, employee0_.VERSION as VERSION2_ from Employee employee0_ where employee0_.EMPLOYEE_ID<3
- エンティティの全プロパティを取得するクエリが実行される。
- クライアントに返すのはプロキシじゃない。
- JDBCのスクロールの機能を使ってアクセスされる。
- 永続コンテキストに格納される。
- ScrollableResultsの中でResultSetやPreparedStatementを持っているので自分でクローズしなきゃだめ。