0

无论如何,我通常为自己调试我的东西,我也有一个替代(臃肿但有效)的解决方案,但我似乎无法在我的以下批处理代码中找出逻辑错误:

private int records = 0;
private Query q;

public void BatchProcessor(String className)
        throws Exception {
    int pageSize = 1000;
    boolean done = false;
    List<Test> resultList = null;

    while (!done) {

        q.setFirstResult(records);
        q.setMaxResults(records+pageSize);
        System.out.println("records: "+records);            

        if (records % pageSize == 0) {
            em.clear();
        }

        resultList = q.getResultList();
        process(resultList);
    }
}

private void process(List<Test> list) {
    Iterator<Test> itAmount = list.iterator();
    while (itAmount.hasNext()) {
        Test dto = itAmount.next();
        records=records+1;
    }
}

输出如下:

记录:0
记录:1000
记录:3000
记录:7000
记录:15000
记录:31000
...

这真让我抓狂。while() 中的每个循环似乎再次从“0”开始,因为 q.setFirstResult() 的数量然后列表变大。该列表每次迭代都会变大,直到发生“内存不足”异常。我也不明白为什么它没有打印出 20000 条记录、40000 条、50000 条等。我完全看不出这段代码中的错误 :( 请问有人有提示吗?

4

2 回答 2

3

你不应该这样做q.setMaxResults(records+pageSize);你应该只做q.setMaxResults(pageSize)

如果随着你的records增加你正在增加MaxResults

Java 文档

查询 setMaxResults(int maxResult)

设置要检索的最大结果数。

由于您的records+pageSize价值,该列表正在增加

records= 0 MaxResults = 1000;
records= 1000 MaxResults = 2000;

它应该总是像

records= 0 MaxResults = 1000;
records= 1000 MaxResults = 1000;
records= 2000 MaxResults = 1000;
于 2012-09-06T12:39:37.993 回答
1

done 永远不会设置为 true,因此它会永远循环。

然后将记录设置为 0,然后设置为 1000,然后设置为 3000,然后设置为 7000,...

所以你的输出也很正常......

private int records = 0;
private Query q;

public void BatchProcessor(String className)
        throws Exception {
    int pageSize = 1000;
    int nbofloops = 0;
    boolean done = false;
    List<Test> resultList = null;

    while (!done) {

        q.setFirstResult(pageSize * nbofloops++;);
        q.setMaxResults(pageSize);
        System.out.println("records: "+records);            

        if (records % pageSize == 0) {
            em.clear();
        }

        resultList = q.getResultList();
        process(resultList);
    }
}

private void process(List<Test> list) {
    Iterator<Test> itAmount = list.iterator();
    while (itAmount.hasNext()) {
        Test dto = itAmount.next();
        records=records+1;
    }
}
于 2012-09-06T12:45:18.847 回答