2016-04-20 30 views
5

Sto utilizzando Hibernate per il mio layer ORM. Cerco di eseguire batch di query HQL in una transazione (non posso usare session.update). Il problema è che anche transaction.commit() si trova alla fine del ciclo, le query di aggiornamento vengono eseguite una alla volta. Esiste un modo per eseguire più query HQL in un'unica transazione?Hibernate aggiornamento batch tramite query 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; 
} 

Apprezzare qualsiasi aiuto.

+0

Non vedo nulla di evidentemente sbagliato nel codice. Gli aggiornamenti si verificheranno sul database uno alla volta, ma non verranno impegnati finché non si chiama commit. Dovresti essere in grado di eseguire il rollback della transazione in qualsiasi momento prima di chiamare commit. Questo è abbastanza standard. Sei solo preoccupato per il numero di round trip nel database? – markwatsonatx

+0

Avere una transazione non significa inviare più aggiornamenti in grandi partite. E ci sono semplicemente troppe cose che non guardano bene nel tuo approccio (vorrei che fosse quello che farai nel codice di produzione). –

+0

Grazie per le tue risposte. Ho bisogno di passare da session.update (item) a questo approccio, e c'è una diminuzione delle prestazioni. – Lasti

risposta

2

Stai utilizzando una transazione di database per registrare tutte le tue dichiarazioni, ma penso che tu voglia utilizzare batch updates.

Basta aggiungere la seguente proprietà di configurazione:

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

Anche così, penso che si dovrebbe usare Hibernate per gestire l'inserimento/aggiornamento/cancellazione affermazioni, come si dovrebbe concentrarsi solo su entity state transitions. Lo dirty checking mechanism può rilevare automaticamente le entità che sono state modificate e Hibernate può generare per te l'istruzione di aggiornamento, che è molto più comoda.