[英]Hibernate Batch Update - Entities are not updated
我有一個批處理過程,它正在重新計算一組實體的數據。 實體列表是通過休眠從數據庫中獲取的:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void recalculateUserData(Long userId){
List<Entity> data = repository.getAllPendingRecalculation(userId);
List<Entity> recalculated = new LinkedList();
for (Entity entity : data){
recalculateEntity(entity, recalculated);
recalculated.add(entity);
flushIfNeeded(recalculated); //every 10 records
}
}
private void recalculateEntity(Entity entity, List<Entity> recalculated){
//do logic
}
private void flush(){
getSession().flush();
getSession().clear();
}
private void flushIfNeeded(List<Entity> data) {
int flushSize = 10
if (data.size() % flushSize == 0){
flush();
}
}
該過程運行時,看起來某些實體變得分離,從而導致兩個症狀:
org.hibernate.LazyInitializationException - could not initialize proxy - no Session
。 flushIfNeeded(...)
工作正常,DB中僅更新前10條記錄。 在我的第一次嘗試中,我嘗試通過在recalculateEntity(...)
內調用session#refresh(entity)
來解決該問題-這解決了延遲初始化問題,但#2中的問題仍然發生:
private void recalculateEntity(Entity entity){
getSession().refresh(entity);
//do logic
}
既然這還沒有解決問題,我考慮過要使用attach(entity)
而不是refresh(entity)
:
private void recalculateEntity(Entity entity){
getSession().attach(entity);
//do logic
}
這似乎可行,但是我的問題是: 為什么這些實體首先被分離?
(我正在使用Hibernate 3.6.10)
正如@galovics解釋的那樣:
問題是您要清除包含所有托管實體的整個會話,從而使它們分離。
Hibernate批處理文檔指出,應使用ScrollableResults
(可解決這些問題)執行批更新,但是在這種情況下,我必須先獲取所有數據,然后再處理它,因為實體計算可能取決於已經計算的實體。 例如,計算實體3可能需要為實體1和實體2計算的數據。
對於這種情況,最好使用Session#attach(entity)
(如代碼所示),使用Session#flush()
而不使用Session#clear()
還是有更好的解決方案?
問題是您要清除包含所有托管實體的整個會話,從而使它們分離。
如果僅使用部分數據,請確保僅獲取它們,然后可以輕松清除整個會話並獲取下一批並進行相同的計算。
關於LazyInitializationException的文章只是為了澄清它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.