Não há "apropriado" o que fazer isso, isso não é o que JPA ou JDO ou qualquer outro ORM se destina a fazer, JDBC direto será sua melhor alternativa, pois você pode configurá-lo para trazer de volta um pequeno número de linhas em uma vez e esvazie-os à medida que são usados, é por isso que existem cursores do lado do servidor.
As ferramentas ORM não são projetadas para processamento em massa, elas são projetadas para permitir que você manipule objetos e tente fazer com que o RDBMS em que os dados são armazenados seja o mais transparente possível, a maioria falha na parte transparente pelo menos em algum grau. Nessa escala, não há como processar centenas de milhares de linhas (Objetos), muito menos milhões com qualquer ORM e executá-lo em qualquer período de tempo razoável por causa do overhead de instanciação do objeto, puro e simples.
Use a ferramenta apropriada. JDBC direto e procedimentos armazenados definitivamente têm um lugar em 2011, especialmente no que eles fazem melhor em comparação com essas estruturas ORM.
Puxar um milhão de qualquer coisa, mesmo de uma forma simples, List<Integer>
não será muito eficiente, independentemente de como você o faz. A maneira correta de fazer o que você está pedindo é simples SELECT id FROM table
, defina como SERVER SIDE
(dependente do fornecedor) e coloque o cursor em FORWARD_ONLY READ-ONLY
e itere sobre isso.
Se você realmente está puxando milhões de ids para processar chamando algum servidor da web com cada um, você terá que fazer algum processamento simultâneo para que isso seja executado em um período de tempo razoável. Puxar com um cursor JDBC e colocar alguns deles por vez em um ConcurrentLinkedQueue e ter um pequeno pool de threads (# CPU / Cores + 1) puxar e processá-los é a única maneira de completar sua tarefa em uma máquina com qualquer " "normal" de RAM, visto que você já está ficando sem memória.
Veja esta resposta também.