JPA:迭代大型结果集的正确模式是什么? [英] JPA: what is the proper pattern for iterating over large result sets?
问题描述
例如,如果表格很大,我怀疑以下情况会爆炸:
List< Model> ; models = entityManager()。createQuery(from Model m,Model.class).getResultList(); (模型模型:模型)
{
System.out.println(model.getId());
$ b 是分页(循环和手动更新 setFirstResult() / setMaxResult()
)真的是最好的解决方案吗?
/ strong>:我要定位的主要用例是一种批处理作业。如果需要很长时间才能运行,这很好。没有涉及Web客户端;我只需要为每一行做点什么,一次一个(或者一些小N)。
http://rads.stackoverflow.com/amzn/click/1932394885\">使用Hibernate的Java持久化给出了一个使用 ScrollableResults
的解决方案,但是它只适用于Hibernate 。因此,看来使用 setFirstResult
/ setMaxResults
和手动迭代确实是必要的。这是我使用JPA的解决方案:
private List< Model> getAllModelsIterable(int offset,int max)
{
return entityManager.createQuery(from Model m,Model.class).setFirstResult(offset).setMaxResults(max).getResultList();
}
然后,像这样使用它:
private void iterateAll()
{
int offset = 0;
列表< Model>楷模; ((models = Model.getAllModelsIterable(offset,100))。size()> 0)
{
entityManager.getTransaction()。begin(); (模型:模型)
{
log.info(用模型做某事:+ model.getId());
}
entityManager.flush();
entityManager.clear();
em.getTransaction()。commit();
offset + = models.size();
}
}
Let's say I have a table with millions of rows. Using JPA, what's the proper way to iterate over a query against that table, such that I don't have all an in-memory List with millions of objects?
For example, I suspect that the following will blow up if the table is large:
List<Model> models = entityManager().createQuery("from Model m", Model.class).getResultList();
for (Model model : models)
{
System.out.println(model.getId());
}
Is pagination (looping and manually updating setFirstResult()
/setMaxResult()
) really the best solution?
Edit: the primary use-case I'm targeting is a kind of batch job. It's fine if it takes a long time to run. There is no web client involved; I just need to "do something" for each row, one (or some small N) at a time. I'm just trying to avoid having them all in memory at the same time.
解决方案 Page 537 of Java Persistence with Hibernate gives a solution using ScrollableResults
, but alas it's only for Hibernate.
So it seems that using setFirstResult
/setMaxResults
and manual iteration really is necessary. Here's my solution using JPA:
private List<Model> getAllModelsIterable(int offset, int max)
{
return entityManager.createQuery("from Model m", Model.class).setFirstResult(offset).setMaxResults(max).getResultList();
}
then, use it like this:
private void iterateAll()
{
int offset = 0;
List<Model> models;
while ((models = Model.getAllModelsIterable(offset, 100)).size() > 0)
{
entityManager.getTransaction().begin();
for (Model model : models)
{
log.info("do something with model: " + model.getId());
}
entityManager.flush();
entityManager.clear();
em.getTransaction().commit();
offset += models.size();
}
}
这篇关于JPA:迭代大型结果集的正确模式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!