使用JPA / EclipseLink修改大量对象

时间:2015-01-28 13:09:34

标签: java jpa eclipselink

我需要迭代50k对象并更改其中的一些字段 我记忆力有限,所以我不想一次把所有50k物品都带入记忆中。
我想用以下代码使用游标来做这件事,但我想知道我使用游标处理的所有对象是否都保留在Entity Manager缓存中。
我不想用偏移量和限制来做这件事的原因是因为数据库需要更加努力,因为每个页面都是一个完整的新查询。
从以前的经验来看,一旦实体经理缓存变大,更新就变得非常慢 所以通常我会在每几百次更新后调用flush和clear 这里的问题是冲洗/清除会破坏光标 我将很乐意学习更新大量对象的最佳方法,而无需将它们全部加载到内存中 有关EclipseLink光标如何在这样的场景中工作的其他信息也很有价值。

JpaQuery<T> jQuery = (JpaQuery<T>) query;
jQuery.setHint(QueryHints.RESULT_SET_TYPE, ResultSetType.ForwardOnly)
              .setHint(QueryHints.SCROLLABLE_CURSOR, true);
Cursor cursor = jQuery.getResultCursor();
Iterator<MyObj> cursorIterator = cursor.iterator();
while (cursorIterator.hasNext()) {
      MyObj myObj = cursorIterator.next();
      ChangeMyObj(myObj);
}
cursor.close();

2 个答案:

答案 0 :(得分:0)

在每页后使用pagination + entityManager.clear()。还要在单个事务中执行每个页面,或者在发生异常后必须创建/获取新的EntityManager(至少在Hibernate中:EntityManager实例在异常后可能处于不一致状态)。

答案 1 :(得分:0)

试试这个示例代码:

    List results;
    int index= 0;
    int max = 100;
    do {
    Query query= manager.createQuery("JPQL QUERY");
query.setMaxResults(max).
setFirstResult(index);
 results = query.getResultList( );
    Iterator it = results.iterator( );
    while (it.hasNext( )) {
    Object c = (Object)it.next( );

    }
entityManager.clear( );
index = index + results.getSize( );
} while (results.size( ) > 0);