SpringBatch JpaPagingItemReader SortOrder

时间:2016-06-08 18:47:05

标签: spring-batch

我使用的是SpringBatch 3.0.7版,Hibernate 4.3.11和H2数据库。使用JpaPagingItemReader时,JPQL是否需要唯一的排序顺序?我发现它是JdbcPagingItemReader所必需的(参见BATCH-2465)。

在一个步骤中,我使用JpaPagingItemReader从数据库加载实体,然后将它们写入平面文件。我希望平面文件包含按JPQL指定的顺序排序的唯一实体。如果我将页面大小设置为小的,如1,然后提供一个JPQL语句,用非唯一键对实体进行排序,我看到同一个实体在输出文件中重复多次。如果我按唯一键排序,则没有“重复”。如果我设置页面大小> =实体总数,那么只有1页,没有“重复”。

根据经验,JpaPagingItemReader似乎要求JPQL具有唯一的排序键。

1 个答案:

答案 0 :(得分:1)

看一下JpaPagingItemReader的实现,你会发现方法doReadPage():

@Override
@SuppressWarnings("unchecked")
protected void doReadPage() {

    EntityTransaction tx = null;

    if (transacted) {
        tx = entityManager.getTransaction();
        tx.begin();

        entityManager.flush();
        entityManager.clear();
    }//end if

    Query query = createQuery().setFirstResult(getPage() * getPageSize()).setMaxResults(getPageSize());

    if (parameterValues != null) {
        for (Map.Entry<String, Object> me : parameterValues.entrySet()) {
            query.setParameter(me.getKey(), me.getValue());
        }
    }

    if (results == null) {
        results = new CopyOnWriteArrayList<T>();
    }
    else {
        results.clear();
    }

    if (!transacted) {
        List<T> queryResult = query.getResultList();
        for (T entity : queryResult) {
            entityManager.detach(entity);
            results.add(entity);
        }//end if
    } else {
        results.addAll(query.getResultList());
        tx.commit();
    }//end if
}

如您所见,对于每个读取的页面,都会为每个页面创建一个新查询。因此,必须确保您的查询始终返回完全相同顺序中相同数量的元素,因此,它需要一个&#39;唯一排序键&# 39 ;.否则,您将有重复项和缺少的条目(每个副本都会有一个缺少的条目,因为总行数将相同)。