Propriedade de hibernação
hibernate.jdbc.batch_size
é uma maneira de hibernar otimizar sua instrução de inserção ou atualização, enquanto o loop de liberação é sobre o esgotamento da memória. Sem batchsize quando você tenta salvar uma entidade hibernate fire 1 insert statement, portanto, se você trabalha com uma coleção grande, para cada save hibernate fire 1 declaração
Imagine o seguinte trecho de código:
for(Entity e : entities){
session.save(e);
}
Aqui o hibernate irá disparar 1 instrução insert por entidade em sua coleção. se você tiver 100 elementos em sua coleção, então 100 instruções de inserção serão acionadas. Essa abordagem não é muito eficiente por 2 motivos principais:
- 1) Você aumenta exponencialmente seu cache de 1º nível e provavelmente terminará em breve com um
OutOfMemoryException
. - 2) Você degrada o desempenho devido à viagem de ida e volta da rede para cada declaração.
hibernate.jdbc.batch_size e o loop de descarga têm 2 propósitos diferentes, mas são complementares.
O Hibernate usa o primeiro para controlar quantas entidades estarão em lote. Sob a capa Hibernate use
java.sql.Statement.addBatch(...)
e executeBatch()
métodos. Então hibernate.jdbc.batch_size diz ao hibernate quantas vezes ele tem que chamar
addBatch()
antes de chamar executeBatch()
. Assim, definir esta propriedade não impede o esgotamento da memória.
Para cuidar da memória, você precisa liberar sua sessão regularmente e esse é o objetivo do loop de liberação.
Quando você escreve:
for(Entity e : entities){
if (i % 100 == 0 && i>0) {
session.flush();
session.clear();
}
}
você está dizendo ao hibernate para liberar e limpar a sessão a cada 100 entidades (você libera memória).
Então, agora, qual é a ligação entre os 2?
Para ser ideal, você deve definir seu
jdbc.batch_size
e seu parâmetro de descarga idêntico. se você definir um parâmetro de flush mais baixo que o batch_size que você escolher, então o hibernate irá liberar a sessão com mais freqüência para que ele crie um pequeno lote até chegar ao tamanho do btach, o que não é eficiente
quando os 2 são iguais, o hibernate só executará lotes de tamanho ideal, exceto o último, se o tamanho da coleção não for um múltiplo do seu batch_size.
Você pode ver o seguinte postar para mais detalhes sobre este último ponto