0

Well, i'm trying to making a batch insert in JPA but i think this don't work.

My method is this :

public void saveBatch(List<? extends AbstractBean> beans) {
    try {
        begin();
        logger.info("Salvando em batch " + beans.size() + " bean(s)");
        for (int i = 0; i < beans.size(); i++) {
        if (i % 50 == 0) {
            entityManager.flush();
            entityManager.clear();
        }
        entityManager.merge(beans.get(i));

        }
        commit();
    } catch (Exception e) {
        logger.error("Ocorreu um erro ao tentar salvar batch. MSG ORIGINAL: "
                + e.getMessage());
        rollback();
        throw new DAOException("Ocorreu um erro ao tentar salvar batch");
    }
    }

My ideia is that each 50 rows the hibernate will make:

insert into tableA values (),(),()...

But watching the log i see one INSERT for each merge() command link this:

insert into tableA values ()
insert into tableA values ()
insert into tableA values ()
insert into tableA values ()

What is wrong ? This is correct ?

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
Ronaldo Lanhellas
  • 2,975
  • 5
  • 46
  • 92
  • what is your JPA impl. It is depending on. Have you modify your JPA conf to enable it ? If yes, how ? – davidxxx Jul 17 '16 at 17:47
  • my jpa is 2.1, using hibernate. I not modified nothing in jpa config. – Ronaldo Lanhellas Jul 17 '16 at 17:57
  • Possible duplicate http://stackoverflow.com/questions/20285347/massive-insert-with-jpa-hibernate – Rob Jul 17 '16 at 19:12
  • Your assumptions are wrong. Hibernate will not generate a single bulky SQL statement but it will rather take a batch of (insert) statements (50 in your case) and pass them onto the database simultaneously in a single round trip (when `EntityManager#flush()` (or commit at the end) is executed) – Tiny Jul 17 '16 at 20:00
  • I read this post but i am already using entityManager and a lowest value batch size = 50 – Ronaldo Lanhellas Jul 17 '16 at 20:01
  • @Tiny if your logic is correct, so the problem is solved but this is at least strange because hibernante is showing inserts before real inserts sql – Ronaldo Lanhellas Jul 17 '16 at 20:28
  • I did not get anything from this, "*Hibernante is showing inserts before real inserts sql*". – Tiny Jul 17 '16 at 20:37
  • Because for me hibernate should show INSERT statement only when really touch the database – Ronaldo Lanhellas Jul 17 '16 at 20:46

1 Answers1

1

Hibernate does not enable batching by default. You will want to consider the following settings (I think at least batch_size is required to get any batch inserts/updates to work):

hibernate.jdbc.batch_size

A non-zero value enables use of JDBC2 batch updates by Hibernate. e.g. recommended values between 5 and 30

hibernate.jdbc.batch_versioned_data

Set this property to true if your JDBC driver returns correct row counts from executeBatch(). It is usually safe to turn this option on. Hibernate will then use batched DML for automatically versioned data. Defaults to false. e.g. true | false

hibernate.order_updates (similarly, hibernate.order_inserts)

Forces Hibernate to order SQL updates by the primary key value of the items being updated. This will result in fewer transaction deadlocks in highly concurrent systems. e.g. true | false

Rob
  • 6,247
  • 2
  • 25
  • 33
  • I added batch_size in persistente.xml but the problem continue. I cant understand why i should use this property if i am controlling it. – Ronaldo Lanhellas Jul 17 '16 at 19:52