2016-11-03 12 views
0

メモリリークを避けるために、テーブルの行数に基づいて動的バッチセレクタを作成しました。しかし、このコードスニペットは、の最後の数千の行をデータベースので検索できないようです。このHibernateページング機構で何が問題になっていますか?

本質的に、コードを以下に示す。明確にするため

System.out.println("Loading the query..."); 
Session session = HibernateUtil.getSessionFactory().openSession(); 

int i = 0; 
int batch = 5000; //process in batches if table is too big 
Long rowCount = (Long) session.createQuery("select count(*) " + cacheDetail.getQuery()).list().get(0); 

System.out.println("Starting execution on " + cacheDetail.getQuery()); 
if (rowCount > batch) { 
    List<Object> list = session.createQuery(cacheDetail.getQuery()) 
      .setFirstResult(i).setMaxResults(batch).list(); 
    while(list.size() == batch || list.size() < batch){ 
     i+=batch; 
     if (list.size() < batch) { 
      list = session.createQuery(cacheDetail.getQuery()) 
        .setFirstResult(i).setMaxResults(list.size()).list(); 
     } else { 
      list = session.createQuery(cacheDetail.getQuery()) 
        .setFirstResult(i).setMaxResults(batch).list(); 
     } 
     //Do some computation, close session 
    } 
} 

を、cacheDetail.getQuery()だけHQL SELECT文である: "TABLEX FROM"。

コード内のどこが間違っていますか?

答えて

1

あなたはそれらのあなただけの最後の結果を取得しているため、あなたは以下の洗練されたコードを見ることができ、単一のリスト(total)に結果を統合されていません。入力用

Session session = HibernateUtil.getSessionFactory().openSession(); 

int i = 0; 
int batch = 5000; //process in batches if table is too big 
Long rowCount = (Long) session.createQuery("select count(*) " + cacheDetail.getQuery()).list().get(0); 

//Create a new list to sum each batch  
List<Object> total = new ArrayList<>(); 

System.out.println("Starting execution on " + cacheDetail.getQuery()); 
if (rowCount > batch) { 
    List<Object> list = session.createQuery(cacheDetail.getQuery()) 
      .setFirstResult(i).setMaxResults(batch).list(); 
    total.addAll(list); 

    while(list.size() == batch || list.size() < batch) { 
     i+=batch; 

     if (list.size() < batch) { 
     list = session.createQuery(cacheDetail.getQuery()) 
       .setFirstResult(i).setMaxResults(list.size()).list(); 
     } else { 
     list = session.createQuery(cacheDetail.getQuery()) 
       .setFirstResult(i).setMaxResults(batch).list(); 
     } 

     total.addAll(list);//add to total 
     //Do some computation, close session 
    } 
} else { //what if row count is less than batch, YOU DID NOT HANDLE 
    List<Object> list = session.createQuery(cacheDetail.getQuery()) 
      .setFirstResult(i).setMaxResults(rowCount).list(); 
      total.addAll(list); 
     //Do some computation, close session 
} 
+0

'while(total.size()

+0

ああ、大丈夫、あなたがポイントを持って、あなたは条件の間、あなたのロジックを持つことができますが、ポイントは合計するための新しいリストを作成し、それに各結果を追加する – developer

+0

私は新しいリストを作成し、それに結果?私はむしろ記憶が非常に繊細であるので、そうではないだろう。編集:どのように私は比較のために私を使用して行くだろうか?これは、バッチをインクリメントするにつれてかなり見やすくなり、行ポインタとしてクエリに使用されています。 –

0

おかげjavaguyおよびST-DDT。あなたのコメントに応じて、私はメモリ内の分散マップに休止状態のオブジェクトをロードしています。私はあなたのソリューションを組み合わせて、このようなものに調整しました(それは、DB変更が起こりにくいrowCount自体を使用しています)。それが正常に動作しますように、また、あなたの入力を希望ようだ:私は本当に私が重複したくないし、むしろ方法処理と同じように、あなたが投稿合計リストを使用してに熱心ではないんだけど

int i = 0; 
int batch = 5000; //process in batches if table is too big 

Long rowCount = (Long) session.createQuery("select count(*) " + cacheDetail.getQuery()).list().get(0); 

System.out.println("Starting execution on " + cacheDetail.getQuery()); 
if (rowCount > batch) { //do batch processing 
    List<Object> list = session.createQuery(cacheDetail.getQuery()) 
      .setFirstResult(i).setMaxResults(batch).list(); 
    //Load objects from list to a map 

    while(list.size() == batch){ 
     i += batch; 
     rowCount -= batch; 
     list = session.createQuery(cacheDetail.getQuery()) 
       .setFirstResult(i).setMaxResults(batch).list(); 
    //Load objects from list to a map 

    } 
    if (rowCount < batch){ 
     System.out.println("Loading the last " + rowCount + " records."); 
     list = session.createQuery(cacheDetail.getQuery()) 
       .setFirstResult(i).setMaxResults((int)(long)rowCount).list(); 
    //load objects from list to map 
    } 

    list = null; 
    session.flush(); 
    session.clear(); 
} 
//Else, use a non paging mechanism to select from DB (trivial) 

をST- DDTは言った。

関連する問題