title: Massive insert with JPA + Hibernate
body: <p>I need to do a massive insert using EJB 3, Hibernate, Spring Data and Oracle. Originally, I am using Spring Data and code is below:</p>
  
  <pre><code>talaoAITDAO.save(taloes);
  </code></pre>
  
  <p>Where talaoAITDAO is a Spring Data <a href="http://docs.spring.io/spring-data/jpa/docs/1.1.0.RELEASE/api/org/springframework/data/jpa/repository/JpaRepository.html" rel="nofollow noreferrer">JpaRepository</a> subclass and taloes is a Collection of TalaoAIT entity. In this entity, Its respective ID has this form:</p>
  
  <pre><code>@Id
  @Column(name = "ID_TALAO_AIT")
  @SequenceGenerator(name = "SQ_TALAO_AIT", sequenceName = "SQ_TALAO_AIT", allocationSize = 1000)
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SQ_TALAO_AIT")
  private Long id;
  </code></pre>
  
  <p>Also this entity has no related entities to do cascade insert.</p>
  
  <p>My problem here, is that all entities are individually inserted (such as <code>INSERT INTO TABLE(col1, col2) VALUES (val1, val2)</code>). Occasionally, it can cause a timeout and all insertions will be rolled back. I would want convert these individual inserts in batch inserts (such as <code>INSERT INTO TABLE(col1, col2) VALUES (val11, val12), (val21, val22), (val31, val32), ...</code>).</p>
  
  <p>Studying alternatives to improve performance, I found <a href="http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html" rel="nofollow noreferrer">this page</a> in hibernate documentation, beyond 
  <a href="https://stackoverflow.com/questions/6687422/hibernate-batch-size-confusion">Hibernate batch size confusion</a> and <a href="http://abramsm.wordpress.com/2008/04/23/hibernate-batch-processing-why-you-may-not-be-using-it-even-if-you-think-you-are/" rel="nofollow noreferrer">this other page</a>. Based on them, I wrote this code:</p>
  
  <pre><code>Session session = super.getEntityManager().unwrap(Session.class);
  int batchSize = 1000;
  for (int i = 0; i &lt; taloes.size(); i++) {
      TalaoAIT talaoAIT = taloes.get(i);
      session.save(talaoAIT);
      if(i % batchSize == 0) {
          session.flush();
          session.clear();
      }
      taloes.add(talaoAIT);
  }
  session.flush();
  session.clear();
  </code></pre>
  
  <p>Also, in peristence.xml, I added these properties:</p>
  
  <pre><code>&lt;property name="hibernate.jdbc.batch_size" value="1000" /&gt;
  &lt;property name="order_inserts" value="true" /&gt;
  </code></pre>
  
  <p>However, although in my tests I had perceived a subtle difference (mainly with big collections and big batch sizes), it was not so big as desirable. In logging console, I saw that Hibernate continued to do individual inserts, not replacing them for massive insert. As in my entity, I am using a Sequence generator I believe that it is not problem (according Hibernate documentation, I would had problem if I was using Identity generator).</p>
  
  <p>So, my question is what can be missing here. Some configuration? Some method not used?</p>
  
  <p>Thanks,</p>
  
  <p>Rafael Afonso.</p>