diff --git a/src/main/java/org/apache/ibatis/cursor/defaults/DefaultCursor.java b/src/main/java/org/apache/ibatis/cursor/defaults/DefaultCursor.java index 2c90d75a7cf..0dbe9cd1dbc 100644 --- a/src/main/java/org/apache/ibatis/cursor/defaults/DefaultCursor.java +++ b/src/main/java/org/apache/ibatis/cursor/defaults/DefaultCursor.java @@ -191,10 +191,6 @@ private class CursorIterator implements Iterator { @Override public boolean hasNext() { - if (isClosed()) { - return false; - } - if (object == null) { object = fetchNextUsingRowBound(); } @@ -203,10 +199,6 @@ public boolean hasNext() { @Override public T next() { - if (isClosed()) { - throw new CursorException("Cursor is closed"); - } - // Fill next with object fetched from hasNext() T next = object; diff --git a/src/test/java/org/apache/ibatis/submitted/cursor_nested/CursorNestedTest.java b/src/test/java/org/apache/ibatis/submitted/cursor_nested/CursorNestedTest.java index 5b4f8410996..6820ec4f47a 100644 --- a/src/test/java/org/apache/ibatis/submitted/cursor_nested/CursorNestedTest.java +++ b/src/test/java/org/apache/ibatis/submitted/cursor_nested/CursorNestedTest.java @@ -103,6 +103,7 @@ public void testCursorWithRowBound() { Iterator iterator = usersCursor.iterator(); + Assert.assertTrue(iterator.hasNext()); User user = iterator.next(); Assert.assertEquals("User3", user.getName()); Assert.assertEquals(2, usersCursor.getCurrentIndex()); diff --git a/src/test/java/org/apache/ibatis/submitted/cursor_simple/CreateDB.sql b/src/test/java/org/apache/ibatis/submitted/cursor_simple/CreateDB.sql index 32ebb72b5c3..88385a279b3 100644 --- a/src/test/java/org/apache/ibatis/submitted/cursor_simple/CreateDB.sql +++ b/src/test/java/org/apache/ibatis/submitted/cursor_simple/CreateDB.sql @@ -25,3 +25,4 @@ insert into users values(1, 'User1'); insert into users values(2, 'User2'); insert into users values(3, 'User3'); insert into users values(4, 'User4'); +insert into users values(5, 'User5'); \ No newline at end of file diff --git a/src/test/java/org/apache/ibatis/submitted/cursor_simple/CursorSimpleTest.java b/src/test/java/org/apache/ibatis/submitted/cursor_simple/CursorSimpleTest.java index 325b814bf3b..c1bc5384442 100644 --- a/src/test/java/org/apache/ibatis/submitted/cursor_simple/CursorSimpleTest.java +++ b/src/test/java/org/apache/ibatis/submitted/cursor_simple/CursorSimpleTest.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; public class CursorSimpleTest { @@ -93,6 +94,10 @@ public void shouldGetAllUser() { Assert.assertEquals("User4", user.getName()); Assert.assertEquals(3, usersCursor.getCurrentIndex()); + user = iterator.next(); + Assert.assertEquals("User5", user.getName()); + Assert.assertEquals(4, usersCursor.getCurrentIndex()); + // Check no more elements Assert.assertFalse(iterator.hasNext()); Assert.assertFalse(usersCursor.isOpen()); @@ -140,7 +145,7 @@ public void testCursorWithRowBound() { try { // RowBound starting at offset 1 and limiting to 2 items - Cursor usersCursor = sqlSession.selectCursor("getAllUsers", null, new RowBounds(1, 2)); + Cursor usersCursor = sqlSession.selectCursor("getAllUsers", null, new RowBounds(1, 3)); Iterator iterator = usersCursor.iterator(); @@ -148,11 +153,41 @@ public void testCursorWithRowBound() { Assert.assertEquals("User2", user.getName()); Assert.assertEquals(1, usersCursor.getCurrentIndex()); + // Calling hasNext() before next() + Assert.assertTrue(iterator.hasNext()); user = iterator.next(); Assert.assertEquals("User3", user.getName()); Assert.assertEquals(2, usersCursor.getCurrentIndex()); + // Calling next() without a previous hasNext() call + user = iterator.next(); + Assert.assertEquals("User4", user.getName()); + Assert.assertEquals(3, usersCursor.getCurrentIndex()); + + Assert.assertFalse(iterator.hasNext()); + Assert.assertFalse(usersCursor.isOpen()); + Assert.assertTrue(usersCursor.isConsumed()); + } finally { + sqlSession.close(); + } + } + + @Test + public void testCursorIteratorNoSuchElementExceptionWithHasNext() { + SqlSession sqlSession = sqlSessionFactory.openSession(); + + Cursor usersCursor = sqlSession.selectCursor("getAllUsers", null, new RowBounds(1, 1)); + try { + Iterator iterator = usersCursor.iterator(); + + User user = iterator.next(); + Assert.assertEquals("User2", user.getName()); + Assert.assertEquals(1, usersCursor.getCurrentIndex()); + Assert.assertFalse(iterator.hasNext()); + iterator.next(); + Assert.fail("We should have failed since we call next() when hasNext() returned false"); + } catch (NoSuchElementException e) { Assert.assertFalse(usersCursor.isOpen()); Assert.assertTrue(usersCursor.isConsumed()); } finally { @@ -160,6 +195,30 @@ public void testCursorWithRowBound() { } } + @Test + public void testCursorIteratorNoSuchElementExceptionNoHasNext() { + SqlSession sqlSession = sqlSessionFactory.openSession(); + + Cursor usersCursor = sqlSession.selectCursor("getAllUsers", null, new RowBounds(1, 1)); + try { + Iterator iterator = usersCursor.iterator(); + + User user = iterator.next(); + Assert.assertEquals("User2", user.getName()); + Assert.assertEquals(1, usersCursor.getCurrentIndex()); + + // Trying next() without hasNext() + iterator.next(); + Assert.fail("We should have failed since we call next() when is no more items"); + } catch (NoSuchElementException e) { + Assert.assertFalse(usersCursor.isOpen()); + Assert.assertTrue(usersCursor.isConsumed()); + } finally { + sqlSession.close(); + } + } + + @Test public void testCursorWithBadRowBound() { SqlSession sqlSession = sqlSessionFactory.openSession(); @@ -285,8 +344,8 @@ public void testCursorUsageAfterClose() throws IOException { // trying next() will fail iterator.next(); - Assert.fail("We should have failed since Cursor is closed"); - } catch (CursorException e) { + Assert.fail("We should have failed with NoSuchElementException since Cursor is closed"); + } catch (NoSuchElementException e) { // We had an exception and current index has not changed Assert.assertEquals(1, usersCursor.getCurrentIndex()); return; @@ -316,17 +375,19 @@ public void shouldGetAllUserUsingAnnotationBasedMapper() { Assert.assertFalse(usersCursor.isOpen()); Assert.assertTrue(usersCursor.isConsumed()); - Assert.assertEquals(3, usersCursor.getCurrentIndex()); + Assert.assertEquals(4, usersCursor.getCurrentIndex()); - Assert.assertEquals(4, userList.size()); + Assert.assertEquals(5, userList.size()); User user = userList.get(0); Assert.assertEquals("User1", user.getName()); user = userList.get(1); Assert.assertEquals("User2", user.getName()); user = userList.get(2); Assert.assertEquals("User3", user.getName()); - user = userList.get(3);; + user = userList.get(3); Assert.assertEquals("User4", user.getName()); + user = userList.get(4); + Assert.assertEquals("User5", user.getName()); } finally { sqlSession.close();