@Override
    public T next() {
        try {
            if (iteratorClosed) {
                throw new NoSuchElementException();
            }
            // If hasNext() has not been called, get the next item here
            if (!hasNextMethodCalled) {
                getNextItem();
            }
            // If there is no next item, throw NoSuchElementException to comply with the Iterator interface
            if (!hasNext) {
                close();
                throw new NoSuchElementException();
            }
            hasNextMethodCalled = false;
            return nextItem;
        } catch (SQLException sqlException) {
            close();
            throw ExceptionUtil.sneakyThrow(sqlException);
        }
    }
@Test
    void testNext() throws SQLException {
        try (Connection connection = DriverManager.getConnection(dbConnectionUrl)) {
            JoinPredicateScanResultSetIterator<String> iterator = createIterator(connection);
            ArrayList<String> tableNameList = new ArrayList<>();
            while (true) {
                try {
                    tableNameList.add(iterator.next());
                } catch (NoSuchElementException exception) {
                    break;
                }
            }
            assertThat(tableNameList).containsAll(EXPECTED_TABLES);

            // Call hasNext() and next() methods one more time after the loop to test their behavior
            assertThat(iterator.hasNext()).isFalse();
            assertThatThrownBy(iterator::next).isInstanceOf(NoSuchElementException.class);
        }
    }