Skip to content

Instantly share code, notes, and snippets.

@akr4
Created August 24, 2011 01:11
Show Gist options
  • Save akr4/1167075 to your computer and use it in GitHub Desktop.
Save akr4/1167075 to your computer and use it in GitHub Desktop.
JPA で大きなデータをループする。あとセッションキャッシュをなんとかする必要がある。
package akr.emp.service;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
public class LazyFetchIterator<T> implements Iterator<T> {
private static final Log LOG = LogFactory.getLog(LazyFetchIterator.class);
private final EntityManager em;
private final TypedQuery<T> query;
private final long totalSize;
private final int pageSize;
private int currentIndex = 0;
private List<T> fetched;
private int fetchedListIndex;
public LazyFetchIterator(EntityManager em, TypedQuery<T> query, long totalSize, int pageSize) {
this.em = em;
this.query = query;
this.totalSize = totalSize;
this.pageSize = pageSize;
}
@Override
public boolean hasNext() {
return currentIndex < totalSize - 1;
}
@Override
public T next() {
if (fetched == null || fetchedListIndex >= fetched.size() - 1) {
fetchNext();
}
if (fetchedListIndex < fetched.size() - 1) {
return getNext();
}
throw new NoSuchElementException();
}
private void fetchNext() {
em.clear();
fetched = query.setFirstResult(currentIndex).setMaxResults(pageSize).getResultList();
fetchedListIndex = 0;
currentIndex += fetched.size();
if (currentIndex % 100000 == 0)
LOG.debug("currentIndex=" + currentIndex);
}
private T getNext() {
T e = fetched.get(fetchedListIndex);
fetchedListIndex++;
return e;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment