spring:
jpa:
properties:
hibernate.jdbc.batch_size: 4
&rewriteBatchedStatements=true
to spring.datasource.url
If turn on show-sql
for enable logging of SQL statements, log will still include multiple insert into
sql. It is because sql rewriting is done at PreparedStatement.executeBatchInternal
after sql statement print at AbstractBatchImpl.getBatchStatement
, and we could verify the real sql by db log:
$ mysqld --verbose --help | grep -A 1 "Default options"
mysql> SET GLOBAL log_output = "FILE";
mysql> SET GLOBAL general_log_file = "/path/to/your/logfile.log";
mysql> SET GLOBAL general_log = 'ON';
$ tail -f /path/to/your/logfile.log
SQL will be like:
178931 16:16:16 66 Query SELECT 1 566 Query SET autocommit=0 566 Query select @@session.tx_read_only 566 Query insert into emp (id, name, dep) values ('1', 'clark', 'IT'),('2', 'robin', 'Market'),('3', 'jeff', 'IT'),('4', 'emily', 'HR') 566 Query insert into emp (id, name, dep) values ('5', 'john', 'Sales')
SimpleJpaRepository.save
(org.springframework.data.jpa.repository.support)AbstractEntityManagerImpl.persist
(org.hibernate.jpa.spi)SessionImpl.persist
(org.hibernate.internal)SessionImpl.firePersist
(org.hibernate.internal)DefaultPersistEventListener.onPersist
(org.hibernate.event.internal)DefaultPersistEventListener.entityIsTransient
(org.hibernate.event.internal)JpaPersistEventListener.saveWithGeneratedId
(org.hibernate.jpa.event.internal.core)AbstractSaveEventListener.performSave
(org.hibernate.event.internal)AbstractSaveEventListener.performSaveOrReplicate
(org.hibernate.event.internal)AbstractSaveEventListener.addInsertAction
(org.hibernate.event.internal)ActionQueue.addAction
(org.hibernate.engine.spi)ActionQueue.addInsertAction
(org.hibernate.engine.spi)ActionQueue.addResolvedEntityInsertAction
(org.hibernate.engine.spi)EntityInsertAction
into EXECUTABLE_LISTS_MAP.get(AbstractEntityInsertAction)
TransactionInterceptor.invoke
(org.springframework.transaction.interceptor): it is called by proxy of business class whose method with @Transactional
TransactionAspectSupport.commitTransactionAfterReturning
(org.springframework.transaction.interceptor): it is called after real business methodSessionImpl.beforeTransactionCompletion
(org.hibernate.internal)SessionImpl.flush
(org.hibernate.internal): get all flush type listeners’ (JpaFlushEventListener
set from JpaIntegrator
) onFlush
DefaultFlushEventListener.onFlush
(org.hibernate.event.internal): call super’s performExecutions
ActionQueue.executeActions
(org.hibernate.engine.spi): loop EXECUTABLE_LISTS_MAP.get(AbstractEntityInsertAction
to execute every action.EntityInsertAction.execute
(org.hibernate.action.internal): call SingleTableEntityPersister.insert
AbstractEntityPersister.insert
(org.hibernate.persister.entity): if use batch, add insert action to BatchingBatchBatchingBatch.addToBatch
(org.hibernate.engine.jdbc.batch.internal): if reached the batch_size, then perform executionBatchingBatch.performExecution
(org.hibernate.engine.jdbc.batch.internal)PreparedStatement.executeBatchInternal
(com.mysql.jdbc): should set rewriteBatchedStatements if want to execute within batch sqlPreparedStatement.executeBatchedInserts
(com.mysql.jdbc): Rewrites the already prepared statement into a multi-value insert and executes enw statement