Author: gbadner
Date: 2007-08-28 20:50:12 -0400 (Tue, 28 Aug 2007)
New Revision: 13957
Modified:
core/trunk/core/src/main/java/org/hibernate/impl/IteratorImpl.java
core/trunk/testsuite/src/test/java/org/hibernate/test/reattachment/ProxyReattachmentTest.java
Log:
HHH-2728 : session.clear() while retrieving objects via an iterator
Modified: core/trunk/core/src/main/java/org/hibernate/impl/IteratorImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/IteratorImpl.java 2007-08-29 00:47:06
UTC (rev 13956)
+++ core/trunk/core/src/main/java/org/hibernate/impl/IteratorImpl.java 2007-08-29 00:50:12
UTC (rev 13957)
@@ -1,4 +1,4 @@
-//$Id: IteratorImpl.java 9944 2006-05-24 21:14:56Z steve.ebersole(a)jboss.com $
+//$Id: IteratorImpl.java 11651 2007-06-07 18:22:50Z steve.ebersole(a)jboss.com $
package org.hibernate.impl;
import java.sql.PreparedStatement;
@@ -34,7 +34,6 @@
private boolean hasNext;
private final String[][] names;
private PreparedStatement ps;
- private Object nextResult;
private HolderInstantiator holderInstantiator;
public IteratorImpl(
@@ -55,14 +54,18 @@
single = types.length==1;
- postNext();
+ // rs.isBeforeFirst() will return false if rs contains no rows
+ hasNext = this.rs.isBeforeFirst();
+ if ( !hasNext ) {
+ log.debug("ResultSet contains no rows");
+ close();
+ }
}
public void close() throws JDBCException {
if (ps!=null) {
try {
log.debug("closing iterator");
- nextResult = null;
session.getBatcher().closeQueryStatement(ps, rs);
ps = null;
rs = null;
@@ -88,44 +91,42 @@
}
}
- private void postNext() throws HibernateException, SQLException {
- this.hasNext = rs.next();
+ private void postNext() throws SQLException {
+ this.hasNext = !rs.isLast();
if (!hasNext) {
log.debug("exhausted results");
close();
}
- else {
+ }
+
+ public boolean hasNext() {
+ return hasNext;
+ }
+
+ public Object next() throws HibernateException {
+ if ( !hasNext ) throw new NoSuchElementException("No more results");
+ try {
log.debug("retrieving next results");
+ rs.next();
boolean isHolder = holderInstantiator.isRequired();
if ( single && !isHolder ) {
- nextResult = types[0].nullSafeGet( rs, names[0], session, null );
+ currentResult = types[0].nullSafeGet( rs, names[0], session, null );
}
else {
- Object[] nextResults = new Object[types.length];
+ Object[] currentResults = new Object[types.length];
for (int i=0; i<types.length; i++) {
- nextResults[i] = types[i].nullSafeGet( rs, names[i], session, null );
+ currentResults[i] = types[i].nullSafeGet( rs, names[i], session, null );
}
if (isHolder) {
- nextResult = holderInstantiator.instantiate(nextResults);
+ currentResult = holderInstantiator.instantiate(currentResults);
}
else {
- nextResult = nextResults;
+ currentResult = currentResults;
}
}
- }
- }
-
- public boolean hasNext() {
- return hasNext;
- }
-
- public Object next() {
- if ( !hasNext ) throw new NoSuchElementException("No more results");
- try {
- currentResult = nextResult;
postNext();
log.debug("returning current results");
return currentResult;
Modified:
core/trunk/testsuite/src/test/java/org/hibernate/test/reattachment/ProxyReattachmentTest.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/reattachment/ProxyReattachmentTest.java 2007-08-29
00:47:06 UTC (rev 13956)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/reattachment/ProxyReattachmentTest.java 2007-08-29
00:50:12 UTC (rev 13957)
@@ -1,5 +1,9 @@
package org.hibernate.test.reattachment;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.HashSet;
+
import junit.framework.Test;
import org.hibernate.junit.functional.FunctionalTestCase;
@@ -73,4 +77,151 @@
s.getTransaction().commit();
s.close();
}
+
+ public void testIterateWithClearTopOfLoop() {
+ Session s = openSession();
+ s.beginTransaction();
+ Set parents = new HashSet();
+ for (int i=0; i<5; i++) {
+ Parent p = new Parent( String.valueOf( i ) );
+ Child child = new Child( "child" + i );
+ child.setParent( p );
+ p.getChildren().add( child );
+ s.save( p );
+ parents.add(p);
+ }
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ int i = 0;
+ for ( Iterator it = s.createQuery( "from Parent" ).iterate(); it.hasNext(); )
{
+ i++;
+ if (i % 2 == 0) {
+ s.flush();
+ s.clear();
+ }
+ Parent p = (Parent) it.next();
+ assertEquals( 1, p.getChildren().size() );
+ }
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ for (Iterator it=parents.iterator(); it.hasNext(); ) {
+ s.delete(it.next());
+ }
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testIterateWithClearBottomOfLoop() {
+ Session s = openSession();
+ s.beginTransaction();
+ Set parents = new HashSet();
+ for (int i=0; i<5; i++) {
+ Parent p = new Parent( String.valueOf( i ) );
+ Child child = new Child( "child" + i );
+ child.setParent( p );
+ p.getChildren().add( child );
+ s.save( p );
+ parents.add(p);
+ }
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ int i = 0;
+ for (Iterator it = s.createQuery( "from Parent" ).iterate(); it.hasNext(); )
{
+ Parent p = (Parent) it.next();
+ assertEquals( 1, p.getChildren().size() );
+ i++;
+ if (i % 2 == 0) {
+ s.flush();
+ s.clear();
+ }
+ }
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ for (Iterator it=parents.iterator(); it.hasNext(); ) {
+ s.delete(it.next());
+ }
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testIterateWithEvictTopOfLoop() {
+ Session s = openSession();
+ s.beginTransaction();
+ Set parents = new HashSet();
+ for (int i=0; i<5; i++) {
+ Parent p = new Parent( String.valueOf( i + 100 ) );
+ Child child = new Child( "child" + i );
+ child.setParent( p );
+ p.getChildren().add( child );
+ s.save( p );
+ parents.add(p);
+ }
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ Parent p = null;
+ for (Iterator it = s.createQuery( "from Parent" ).iterate(); it.hasNext(); )
{
+ if ( p != null) { s.evict(p); }
+ p = (Parent) it.next();
+ assertEquals( 1, p.getChildren().size() );
+ }
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ for (Iterator it=parents.iterator(); it.hasNext(); ) {
+ s.delete(it.next());
+ }
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testIterateWithEvictBottomOfLoop() {
+ Session s = openSession();
+ s.beginTransaction();
+ Set parents = new HashSet();
+ for (int i=0; i<5; i++) {
+ Parent p = new Parent( String.valueOf( i + 100 ) );
+ Child child = new Child( "child" + i );
+ child.setParent( p );
+ p.getChildren().add( child );
+ s.save( p );
+ parents.add(p);
+ }
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ for (Iterator it = s.createQuery( "from Parent" ).iterate(); it.hasNext(); )
{
+ Parent p = (Parent) it.next();
+ assertEquals( 1, p.getChildren().size() );
+ s.evict(p);
+ }
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ for (Iterator it=parents.iterator(); it.hasNext(); ) {
+ s.delete(it.next());
+ }
+ s.getTransaction().commit();
+ s.close();
+ }
}
Show replies by date