在列表中生成大量数据并生成文件

时间:2014-09-15 19:38:37

标签: java mysql hibernate jpa out-of-memory

我在数据库中有一个包含大约230万条记录的表。

我需要通过java / web应用程序将此数据导出到csv文件。

我正在使用JPA / Hibernate。但我遇到了麻烦。

HibernateEntityManager hem = this.getEntityManager().unwrap(HibernateEntityManager.class);
    Session session = hem.getSession();
    org.hibernate.Query qu = 
        session.createSQLQuery("select li.* from ligacoes li").
            setFetchSize(Integer.MIN_VALUE).setReadOnly(true);
    ScrollableResults r = qu.scroll(ScrollMode.FORWARD_ONLY);

    int count = 0;
    while (r.next()) {

但是当程序读取大约200,000条记录时会引发异常:

Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]"  
java.lang.OutOfMemoryError: Java heap space

我尝试过其他方法,但我仍然遇到困难。我无法直接从数据库导出数据。必须通过此应用程序导出数据。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。

我拆分了查询。我没有带一个非常大的列表,而是多次带一个小列表。分页。

        HibernateEntityManager hem = this.getEntityManager().unwrap(HibernateEntityManager.class);
        Session session = hem.getSession();

        int pageIn = 1;
        int pageFim = 20000;
        boolean fim = false;
        int count = 0;

        while (!fim) {
            ++count;
            org.hibernate.Query qu = session.createSQLQuery("select li.* from ligacoes li where li.operadora='81' "
                    + "and length(li.numero_destino) < 8 and li.valor_contrato <> '0'");
            qu.setFirstResult(pageIn - 1);
            qu.setMaxResults(pageFim);
            List<Ligacoes> chamadasVivo = new ArrayList<>(objectToLigacoes(qu.list()));

            count += pageFim;

            if (chamadasVivo.size() <= 0) {
                break;
            }

            for (Ligacoes li : chamadasVivo) {
                //append the file...

            }

            if (count % 100000 == 0) {
                session.flush();
                session.clear();
            }

            pageIn += pageFim;
        }