public Collection<MUCRoomRetiree> getRetirees(String mucServiceName, int startIndex, int numResults) {

        Long serviceID = getMultiUserChatServiceID(mucServiceName);
        List<MUCRoomRetiree> retirees = new ArrayList<>();
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            con = DbConnectionManager.getConnection();

            if ((startIndex == 0) && (numResults == Integer.MAX_VALUE)) {
                // MSSQL differentiates between client-cursored and server-cursored result sets. For server-cursored result
                // sets, the fetch buffer and scroll window are the same size (as opposed to fetch buffer containing all
                // the rows). To hint that a server-cursored result set is desired, it should be configured to be 'forward
                // only' as well as 'read only'.
                pstmt = con.prepareStatement(GET_RETIREES, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
                pstmt.setLong(1, serviceID);
                // Set the fetch size. This will prevent some JDBC drivers from trying
                // to load the entire result set into memory.
                DbConnectionManager.setFetchSize(pstmt, 500);
                pstmt.setFetchDirection(ResultSet.FETCH_FORWARD);
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    retirees.add(new MUCRoomRetiree(
                        rs.getString("name"),
                        rs.getString("alternateJID"),
                        rs.getString("reason"),
                        rs.getTimestamp("retiredAt")
                    ));
                }
            } else {
                pstmt = DbConnectionManager.createScrollablePreparedStatement(con, GET_RETIREES);
                pstmt.setLong(1, serviceID);
                // This handles the paging at the database level
                DbConnectionManager.limitRowsAndFetchSize(pstmt, startIndex, numResults);
                rs = pstmt.executeQuery();
                // This positions the cursor at the start of the requested page
                DbConnectionManager.scrollResultSet(rs, startIndex);
                int count = 0;
                while (rs.next() && count < numResults) {
                    retirees.add(new MUCRoomRetiree(
                        rs.getString("name"),
                        rs.getString("alternateJID"),
                        rs.getString("reason"),
                        rs.getTimestamp("retiredAt")
                    ));
                    count++;
                }
            }

            if (Log.isDebugEnabled()) {
                Log.debug("Retired rooms found: {}", retirees.size());
            }
        } catch (SQLException e) {
            Log.error(e.getMessage(), e);
        } finally {
            DbConnectionManager.closeConnection(rs, pstmt, con);
        }

        return retirees;
    }
Gets the retirees for a MUC service.

@param mucServiceName the name of the MUC service.
@param startIndex the index of the first result to return.
@param numResults the maximum number of results to return.
@return a collection of MUCRoomRetiree objects.
xmppserver/src/main/java/org/jivesoftware/openfire/muc/MultiUserChatManager.java