fresh_dev
fresh_dev

Reputation: 6774

Hibernate batch update doesn't work

i want to use hibernate batch update, i tried the batch insert and it works fine, here's the configuration i am using for hibernate :

<property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQLDialect
                hibernate.hbm2ddl.auto=update
                hibernate.show_sql=false
                hibernate.jdbc.fetch_size=100
                hibernate.jdbc.batch_size=100
                hibernate.jdbc.batch_versioned_data=true
                hibernate.order_inserts=true
                hibernate.order_updates=true
                hibernate.cache.use_query_cache=false
                hibernate.cache.use_second_level_cache=false

            </value>
        </property>

and here's the DAO code:

public void updateBulkEmployees(List<Employee> employees) throws Exception {

        for (int i = 0; i < employees.size(); i++) {
            sessionFactory.getCurrentSession().update(employees.get(i));
            if (i % 100 == 0) {
                sessionFactory.getCurrentSession().flush();
                sessionFactory.getCurrentSession().clear();
                log.debug("Flushing batch:" + (int) (i / 100));
            }            

        }

            sessionFactory.getCurrentSession().flush();
            sessionFactory.getCurrentSession().clear();

    }

ISSUE: i can notice that the method execution takes so much time (exact same time that's taken without using batching), so the batch update is not working, am i missing something in configuration or doing something wrong ? please advise, thanks.

Upvotes: 0

Views: 3009

Answers (2)

Eric Taix
Eric Taix

Reputation: 908

How do you know that batch insert works ? Watch mysql.log is the only way to know if batch insert/update works or not (Hibernate always logs single query even if batch is used).

To use batch with MySQL, you have to set a specific JDBC parameter in your URL (Hibernate batch uses JDBC batch feature). Try with :

http://your_host:your_port/database?rewriteBatchedStatements=true

And don't use GenerationType.AUTO or GenerationType.IDENTITY as Id generator. Hibernate disable silently batch feature in this case.

Tips: Intermediate flush is only required to avoid an OutOfMemory. Hibernate try to query the database as last as possible, so if you try to update 1000000 entities it will keep all entities in memory until commit.

Upvotes: 1

Dmitry Negoda
Dmitry Negoda

Reputation: 3189

Shouldn't the second "sessionFactory.getCurrentSession().flush();" be outside of the loop?

Upvotes: 0

Related Questions