spring:
jpa:
properties:
hibernate.jdbc.batch_size: 4
&rewriteBatchedStatements=true to spring.datasource.urlIf 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 @TransactionalTransactionAspectSupport.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) onFlushDefaultFlushEventListener.onFlush (org.hibernate.event.internal): call super’s performExecutionsActionQueue.executeActions (org.hibernate.engine.spi): loop EXECUTABLE_LISTS_MAP.get(AbstractEntityInsertAction to execute every action.EntityInsertAction.execute (org.hibernate.action.internal): call SingleTableEntityPersister.insertAbstractEntityPersister.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