HHH-2728 : session.clear() while retrieving objects via an iterator

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@13957 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gail Badner 2007-08-29 00:50:12 +00:00
parent 072b3cf623
commit 50a010566b
2 changed files with 182 additions and 30 deletions

View File

@ -1,4 +1,4 @@
//$Id: IteratorImpl.java 9944 2006-05-24 21:14:56Z steve.ebersole@jboss.com $
//$Id: IteratorImpl.java 11651 2007-06-07 18:22:50Z steve.ebersole@jboss.com $
package org.hibernate.impl;
import java.sql.PreparedStatement;
@ -34,7 +34,6 @@ public final class IteratorImpl implements HibernateIterator {
private boolean hasNext;
private final String[][] names;
private PreparedStatement ps;
private Object nextResult;
private HolderInstantiator holderInstantiator;
public IteratorImpl(
@ -55,14 +54,18 @@ public final class IteratorImpl implements HibernateIterator {
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 @@ public final class IteratorImpl implements HibernateIterator {
}
}
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 {
log.debug("retrieving next results");
boolean isHolder = holderInstantiator.isRequired();
if ( single && !isHolder ) {
nextResult = types[0].nullSafeGet( rs, names[0], session, null );
}
else {
Object[] nextResults = new Object[types.length];
for (int i=0; i<types.length; i++) {
nextResults[i] = types[i].nullSafeGet( rs, names[i], session, null );
}
if (isHolder) {
nextResult = holderInstantiator.instantiate(nextResults);
}
else {
nextResult = nextResults;
}
}
}
}
public boolean hasNext() {
return hasNext;
}
public Object next() {
public Object next() throws HibernateException {
if ( !hasNext ) throw new NoSuchElementException("No more results");
try {
currentResult = nextResult;
log.debug("retrieving next results");
rs.next();
boolean isHolder = holderInstantiator.isRequired();
if ( single && !isHolder ) {
currentResult = types[0].nullSafeGet( rs, names[0], session, null );
}
else {
Object[] currentResults = new Object[types.length];
for (int i=0; i<types.length; i++) {
currentResults[i] = types[i].nullSafeGet( rs, names[i], session, null );
}
if (isHolder) {
currentResult = holderInstantiator.instantiate(currentResults);
}
else {
currentResult = currentResults;
}
}
postNext();
log.debug("returning current results");
return currentResult;

View File

@ -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 @@ public class ProxyReattachmentTest extends FunctionalTestCase {
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();
}
}