No caso do Oracle, me recomendaram uma vez fazer a consulta retornar todos os registros e fazer a paginação na iteração do resultset, pecorrendo os dados que interessa e descartando o resto.
Isso foi a primeira coisa que eu fiz :D. E achei umas páginas dizendo que o hibernate não faz paginação com Sybase, outras dizendo que tem problemas, procurei bastante mesmo.
Bah cara, imagina se tu tem 1 zetalhão™ de registros, trazer tudo e depois paginar acho que não é uma boa, o ideal é trazer já do banco somente os registro que tu quer, ou seja, já paginado.
Não é pra trazer tudo, é para trazer até o que interessa e descartar o resto. O executeQuery() não traz nenhum registro, ele só pede ao banco para montar a consulta, quem traz os registros é o next() do resultset.
Se você faz uma consulta de 1 zetalhão™ de registros (executeQuery()), mas só pede para o banco 10 registros (10 chamadas rs.next()), isso vai ser bem rápido. E é nesse ponto que aquele esquema funciona, você só traz até onde interessa.
Lembrando que isso tudo é com base no Oracle, que não possui uma instrução específica para paginação e as gambiarras disponíveis não funcionam ou são extremamente pesadas (usar rownum e paginar usando sub-select, respectivamente).