2016-06-08 61 views
0

我正在使用SpringBatch版本3.0.7,Hibernate 4.3.11和H2數據庫。當使用JpaPagingItemReader時,JPQL是否需要唯一的排序順序?我發現它是JdbcPagingItemReader所必需的(請參閱BATCH-2465)。SpringBatch JpaPagingItemReader SortOrder

在一個步驟中,我使用JpaPagingItemReader從數據庫加載實體,然後將它們寫入到一個平面文件中。我期望平面文件包含按照JPQL指定的順序排序的唯一實體。如果我將頁面大小設置爲小一點,比如1,然後提供一個JPQL語句來排序具有非唯一鍵的實體,我會看到同一個實體在輸出文件中重複多次。如果我按唯一鍵排序,則不存在「重複」。如果我將頁面大小設置爲> =實體總數,那麼只有1頁,沒有「重複」。

經驗上看來,JpaPagingItemReader需要JPQL具有唯一的排序鍵。

回答

0

在看看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 
} 

正如你所看到的,對於每個被讀取頁面時,會爲每個頁面創建一個新的查詢。因此,必須確保您的查詢始終返回相同順序的確切元素的相同數量相同數量的,因此,它需要一個「唯一排序鍵」。否則,您將會有重複項和缺失項(每個重複項都會有一個缺失項,因爲總行數將相同)。

+0

這非常合理。我認爲實施是理所當然的。我對它執行了一個單一查詢的內部思路,它在內部返回整個結果,然後在調用getPage()時將這些結果分塊。感謝Hansjoerg的解釋。 – Randy

相關問題