Skip to content

Commit 3176cb8

Browse files
committed
Merge pull request #667 from gdarmont/pr-660
Fixes #660 : Can not fetch an object from Cursor when a RowBounds is used
2 parents 0cb3d79 + 3447c8f commit 3176cb8

File tree

4 files changed

+69
-14
lines changed

4 files changed

+69
-14
lines changed

src/main/java/org/apache/ibatis/cursor/defaults/DefaultCursor.java

-8
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,6 @@ private class CursorIterator implements Iterator<T> {
191191

192192
@Override
193193
public boolean hasNext() {
194-
if (isClosed()) {
195-
return false;
196-
}
197-
198194
if (object == null) {
199195
object = fetchNextUsingRowBound();
200196
}
@@ -203,10 +199,6 @@ public boolean hasNext() {
203199

204200
@Override
205201
public T next() {
206-
if (isClosed()) {
207-
throw new CursorException("Cursor is closed");
208-
}
209-
210202
// Fill next with object fetched from hasNext()
211203
T next = object;
212204

src/test/java/org/apache/ibatis/submitted/cursor_nested/CursorNestedTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public void testCursorWithRowBound() {
103103

104104
Iterator<User> iterator = usersCursor.iterator();
105105

106+
Assert.assertTrue(iterator.hasNext());
106107
User user = iterator.next();
107108
Assert.assertEquals("User3", user.getName());
108109
Assert.assertEquals(2, usersCursor.getCurrentIndex());

src/test/java/org/apache/ibatis/submitted/cursor_simple/CreateDB.sql

+1
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ insert into users values(1, 'User1');
2525
insert into users values(2, 'User2');
2626
insert into users values(3, 'User3');
2727
insert into users values(4, 'User4');
28+
insert into users values(5, 'User5');

src/test/java/org/apache/ibatis/submitted/cursor_simple/CursorSimpleTest.java

+67-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.ArrayList;
3434
import java.util.Iterator;
3535
import java.util.List;
36+
import java.util.NoSuchElementException;
3637

3738
public class CursorSimpleTest {
3839

@@ -93,6 +94,10 @@ public void shouldGetAllUser() {
9394
Assert.assertEquals("User4", user.getName());
9495
Assert.assertEquals(3, usersCursor.getCurrentIndex());
9596

97+
user = iterator.next();
98+
Assert.assertEquals("User5", user.getName());
99+
Assert.assertEquals(4, usersCursor.getCurrentIndex());
100+
96101
// Check no more elements
97102
Assert.assertFalse(iterator.hasNext());
98103
Assert.assertFalse(usersCursor.isOpen());
@@ -140,26 +145,80 @@ public void testCursorWithRowBound() {
140145

141146
try {
142147
// RowBound starting at offset 1 and limiting to 2 items
143-
Cursor<User> usersCursor = sqlSession.selectCursor("getAllUsers", null, new RowBounds(1, 2));
148+
Cursor<User> usersCursor = sqlSession.selectCursor("getAllUsers", null, new RowBounds(1, 3));
144149

145150
Iterator<User> iterator = usersCursor.iterator();
146151

147152
User user = iterator.next();
148153
Assert.assertEquals("User2", user.getName());
149154
Assert.assertEquals(1, usersCursor.getCurrentIndex());
150155

156+
// Calling hasNext() before next()
157+
Assert.assertTrue(iterator.hasNext());
151158
user = iterator.next();
152159
Assert.assertEquals("User3", user.getName());
153160
Assert.assertEquals(2, usersCursor.getCurrentIndex());
154161

162+
// Calling next() without a previous hasNext() call
163+
user = iterator.next();
164+
Assert.assertEquals("User4", user.getName());
165+
Assert.assertEquals(3, usersCursor.getCurrentIndex());
166+
167+
Assert.assertFalse(iterator.hasNext());
168+
Assert.assertFalse(usersCursor.isOpen());
169+
Assert.assertTrue(usersCursor.isConsumed());
170+
} finally {
171+
sqlSession.close();
172+
}
173+
}
174+
175+
@Test
176+
public void testCursorIteratorNoSuchElementExceptionWithHasNext() {
177+
SqlSession sqlSession = sqlSessionFactory.openSession();
178+
179+
Cursor<User> usersCursor = sqlSession.selectCursor("getAllUsers", null, new RowBounds(1, 1));
180+
try {
181+
Iterator<User> iterator = usersCursor.iterator();
182+
183+
User user = iterator.next();
184+
Assert.assertEquals("User2", user.getName());
185+
Assert.assertEquals(1, usersCursor.getCurrentIndex());
186+
155187
Assert.assertFalse(iterator.hasNext());
188+
iterator.next();
189+
Assert.fail("We should have failed since we call next() when hasNext() returned false");
190+
} catch (NoSuchElementException e) {
156191
Assert.assertFalse(usersCursor.isOpen());
157192
Assert.assertTrue(usersCursor.isConsumed());
158193
} finally {
159194
sqlSession.close();
160195
}
161196
}
162197

198+
@Test
199+
public void testCursorIteratorNoSuchElementExceptionNoHasNext() {
200+
SqlSession sqlSession = sqlSessionFactory.openSession();
201+
202+
Cursor<User> usersCursor = sqlSession.selectCursor("getAllUsers", null, new RowBounds(1, 1));
203+
try {
204+
Iterator<User> iterator = usersCursor.iterator();
205+
206+
User user = iterator.next();
207+
Assert.assertEquals("User2", user.getName());
208+
Assert.assertEquals(1, usersCursor.getCurrentIndex());
209+
210+
// Trying next() without hasNext()
211+
iterator.next();
212+
Assert.fail("We should have failed since we call next() when is no more items");
213+
} catch (NoSuchElementException e) {
214+
Assert.assertFalse(usersCursor.isOpen());
215+
Assert.assertTrue(usersCursor.isConsumed());
216+
} finally {
217+
sqlSession.close();
218+
}
219+
}
220+
221+
163222
@Test
164223
public void testCursorWithBadRowBound() {
165224
SqlSession sqlSession = sqlSessionFactory.openSession();
@@ -285,8 +344,8 @@ public void testCursorUsageAfterClose() throws IOException {
285344
// trying next() will fail
286345
iterator.next();
287346

288-
Assert.fail("We should have failed since Cursor is closed");
289-
} catch (CursorException e) {
347+
Assert.fail("We should have failed with NoSuchElementException since Cursor is closed");
348+
} catch (NoSuchElementException e) {
290349
// We had an exception and current index has not changed
291350
Assert.assertEquals(1, usersCursor.getCurrentIndex());
292351
return;
@@ -316,17 +375,19 @@ public void shouldGetAllUserUsingAnnotationBasedMapper() {
316375

317376
Assert.assertFalse(usersCursor.isOpen());
318377
Assert.assertTrue(usersCursor.isConsumed());
319-
Assert.assertEquals(3, usersCursor.getCurrentIndex());
378+
Assert.assertEquals(4, usersCursor.getCurrentIndex());
320379

321-
Assert.assertEquals(4, userList.size());
380+
Assert.assertEquals(5, userList.size());
322381
User user = userList.get(0);
323382
Assert.assertEquals("User1", user.getName());
324383
user = userList.get(1);
325384
Assert.assertEquals("User2", user.getName());
326385
user = userList.get(2);
327386
Assert.assertEquals("User3", user.getName());
328-
user = userList.get(3);;
387+
user = userList.get(3);
329388
Assert.assertEquals("User4", user.getName());
389+
user = userList.get(4);
390+
Assert.assertEquals("User5", user.getName());
330391

331392
} finally {
332393
sqlSession.close();

0 commit comments

Comments
 (0)