@Override
    public boolean hasNext() {
        try {
            if (iteratorClosed) {
                return false;
            }
            getNextItem();
            if (!hasNext) {
                close();
            }
            hasNextMethodCalled = true;
            return hasNext;
        } catch (SQLException sqlException) {
            close();
            throw ExceptionUtil.sneakyThrow(sqlException);
        }
    }
@Test
    void testHasNext() throws SQLException {
        try (Connection connection = DriverManager.getConnection(dbConnectionUrl)) {
            JoinPredicateScanResultSetIterator<String> iterator = createIterator(connection);
            ArrayList<String> tableNameList = new ArrayList<>();
            while (iterator.hasNext()) {
                tableNameList.add(iterator.next());
            }
            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);
        }
    }