Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate - how to verify if batch insert is really performed

Technology stack: Oracle database 11.2.0.2, Java 1.6, Hibernate 3.6.6.Final.

I am new to hibernate, apologize if this is trivial.

The following code was supposed to put some optimization:

Transaction tx = session.beginTransaction();
for (int i = 0; i < 10; i++) {
   POJO pojo = new POJO(i);
   session.save(pojo);
}
tx.commit();

hibernate.cfg.xml has the following entry

<property name="jdbc.batch_size">500</property>

How can I verify, if hibernate really batches all these inserts? If it performs 10 inserts than there is no gain. One idea is to put the jdbc plain query right after save() that checks if the record was added to db:

String query = "retrieve previously added element"
PreparedStatement stmt = session.connection().prepareStatement(query.toString());
Result rs = statement.executeQuery();
/** check contents of rs */

In my case it returns a non empty set with previously added element. Does it mean anything? How else can I check if batching works.

thanks in advance

like image 959
Łukasz Avatar asked Feb 02 '17 12:02

Łukasz


2 Answers

You need to add "BatchingBatch" logger to your logging provider.

org.hibernate.engine.jdbc.batch.internal.BatchingBatch

Than you will be able to see in the logs something like:

2018-02-20 17:33:41.279 DEBUG 6280 --- [           main] o.h.e.jdbc.batch.internal.BatchingBatch  : Executing batch size: 19

Unless you see this message,batching is not working.

Tested with Hibernate Version:5.2.12

like image 191
selman Avatar answered Sep 20 '22 15:09

selman


To check what is actually flushed to the database then configure your logging properties as follows:

log4j.rootLogger=info, stdout
# basic log level for all messages
log4j.logger.org.hibernate=debug

# SQL statements and parameters
log4j.logger.org.hibernate.SQL=debug
log4j.logger.org.hibernate.type.descriptor.sql=trace

and add this to your hibernate.cfg.xml

<property name="show_sql">true</property>

Then you can see what is actually sent to the db..

With batch you should have output like:

insert into Pojo (id , titel) values (1, 'val1') , (2, 'val2') ,(3, 'val3')

Additionally here is a good post that has some tips about how to most efficiently take advantage of the batch processing: article

For example you might consider flushing after every ${jdbc.batch_size} saves.

Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    Cart cart = new Cart(...);
    customer.setCart(cart) // note we are adding the cart to the customer, so this object 
     // needs to be persisted as well
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}
tx.commit();
like image 36
Maciej Kowalski Avatar answered Sep 20 '22 15:09

Maciej Kowalski