2016-04-20 40 views
5

Używam Hibernuj dla mojej warstwy ORM. Próbuję uruchomić partia zapytań HQL w jednej transakcji (nie mogę użyć session.update). Problem polega na tym, że nawet transakcja transaction.commit() znajduje się na końcu pętli, zapytania aktualizacji są wykonywane jeden po drugim. Czy istnieje sposób na uruchamianie wielu kwerend HQL w jednej transakcji?Aktualizacja wsadowa hibernacji przy użyciu kwerendy HQL

public void updateItems() { 
    t = session.beginTransaction(); 
    for (int i = 0; i < itemList.size(); i++) { 
     Query q = createUpdateQuery(session, itemList.get(i));  
     q.executeUpdate(); //updating one by one, and not waiting for transaction commit 
    } 
    t.commit(); 
} 



Query createUpdateQuery(Session session, Item item) { 
    Query q = session.createQuery(
       "Update Item i set i.notes=:notes, i.time=:time, i.counter=:counter, i.status=:status Where i.id=:id and i.time=:time"); 

    q.setParameter("time", item.getTime()); 
    q.setParameter("status", item.getStatus()); 
    q.setParameter("notes", item.getNotes()); 
    q.setParameter("id", item.getId()); 
    return q; 
} 

Doceń każdą pomoc.

+0

Nie widzę niczego wyraźnie nie tak z Twoim kodem. Aktualizacje będą pojawiać się w bazie danych jeden po drugim, ale nie zostaną zatwierdzone, dopóki nie wywołasz commit. Powinieneś być w stanie wycofać transakcję w dowolnym momencie przed wywołaniem zatwierdzenia. To jest dość standardowe. Czy martwisz się o liczbę podróży w obie strony do bazy danych? – markwatsonatx

+0

Posiadanie jednej transakcji nie oznacza wysyłania wielu aktualizacji w dużej dużej partii. I jest po prostu zbyt wiele rzeczy, które nie wyglądają dobrze w twoim podejściu (chciałbym, żeby to było to, co zamierzasz zrobić w kodzie produkcyjnym). –

+0

Dzięki za odpowiedzi. Potrzebuję zmienić sesję session.update (element) na to podejście, i następuje spadek wydajności. – Lasti

Odpowiedz

2

Używasz transakcji bazy danych do zarejestrowania wszystkich swoich wyciągów, ale myślę, że chcesz użyć batch updates.

Wystarczy dodać następującą właściwość konfiguracji:

<property name="hibernate.jdbc.batch_size" value="10"/> 

Mimo to, myślę, że należy użyć Hibernacja zarządzać insert/update/delete oświadczenia, jak należy skupić się tylko na entity state transitions. dirty checking mechanism może automatycznie wykryć jednostki, które zostały zmodyfikowane, a Hibernate może wygenerować dla ciebie instrukcję aktualizacji, co jest znacznie wygodniejsze.