Iberna la proprietà hibernate.jdbc.batch_size
è un modo per l'ibernazione per ottimizzare la tua istruzione di inserimento o aggiornamento mentre il ciclo di svuotamento riguarda l'esaurimento della memoria.
Senza batchsize quando si tenta di salvare un'entità ibernate fire 1 istruzione insert, quindi se si lavora con una grande raccolta, per ogni istruzione save hibernate fire 1
Immagina il seguente blocco di codice:
for(Entity e : entities){
session.save(e);
}
Qui hibernate attiverà 1 istruzione di inserimento per entità nella tua raccolta. se hai 100 elementi nella tua raccolta, 100 istruzioni di inserimento verranno attivate. Questo approccio non è molto efficiente per 2 motivi principali:
- 1) Aumenti esponenzialmente la tua cache di 1° livello e probabilmente finirai presto con una
OutOfMemoryException
. - 2) Il rendimento è peggiorato a causa dell'andata e ritorno della rete per ogni affermazione.
hibernate.jdbc.batch_size e il ciclo di lavaggio hanno 2 scopi diversi ma sono complementari.
Hibernate usa il primo per controllare quante entità saranno in batch. Sotto la copertura Hibernate usa java.sql.Statement.addBatch(...)
e executeBatch()
metodi.
Quindi hibernate.jdbc.batch_size dice a Hibernate quante volte deve chiamare addBatch()
prima di chiamare executeBatch()
.
Quindi l'impostazione di questa proprietà non impedisce l'esaurimento della memoria.
Per prenderti cura della memoria devi svuotare la tua sessione regolarmente e questo è lo scopo del flushing loop.
Quando scrivi :
for(Entity e : entities){
if (i % 100 == 0 && i>0) {
session.flush();
session.clear();
}
}
stai dicendo a Hibernate di svuotare e cancellare la sessione ogni 100 entità (rilasci memoria).
Quindi ora qual è il collegamento tra i 2 ?
Per essere ottimale devi definire il tuo jdbc.batch_size
e il tuo parametro di lavaggio è identico.
se definisci un parametro flush inferiore a batch_size che scegli in modo ibernato cancellerà la sessione più frequentemente in modo da creare un piccolo batch fino a quando non arriva a btach size che non è efficiente
quando i 2 sono uguali, l'ibernazione eseguirà solo batch di dimensioni ottimali tranne l'ultimo se la dimensione della raccolta non è un multiplo di batch_size.
Puoi vedere il seguente post per maggiori dettagli su quest'ultimo punto