title: Saving multiple entities by multiple threads with hibernate
body: <p>I'd like to save new entities by multiple threads with hibernate. </p>
  
  <p>OBS: I can't use batch process on client.</p>
  
  <p>So I made this structure:</p>
  
  <pre><code>+-----------------+
  |+------------------+
  ||+------------------+     +-----------------------------------------------+
  |||                  |     | Each thread do these steps:                   |
  ||| Multiple Threads |     |  - get EntityManagerFactory                   |
  |||                  |---&gt; |  - create Entity Manager                      |
  ||| Creating new     |     |  - begin new transaction                      |
  +||    Entities on   |     |  - create new entity (with autoincrement id)  |
   +|        Hibernate |     |  - persist                                    |
    +------------------+     |  - commit the transaction                     |
                             |  - close the entity manager                   |
                             +-----------------------------------------------+
  </code></pre>
  
  <p>The entity:</p>
  
  <pre><code>@Entity
  @Table(name="EN_TEST")
  public class EnTest {
      private long id;
  
      private String name;
  
      public EnTest() {
      }
  
      @Id
      @GeneratedValue(generator="increment")
      @GenericGenerator(name="increment", strategy = "increment")
      @Column(name = "ID")
      public long getId() {
          return id;
      }
  
      @SuppressWarnings("unused")
      private void setId(long id) {
          this.id = id;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      @Column(length = 20)
      public String getName() {
          return name;
      }
  }
  </code></pre>
  
  <p>The java stuff (DBHandler):</p>
  
  <pre><code>// just to get the session factory
  public class DBHandler {
      private static DBHandler dbHandler;
  
      private static EntityManager entityManager;
  
      public static DBHandler get() {
          if (dbHandler == null)  {
              dbHandler = new DBHandler();
          }
  
          return dbHandler;
      }
  
      private DBHandler() {
          try {
              this.sessionFactory = Persistence.createEntityManagerFactory("a_persistence_unit");
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      private EntityManagerFactory sessionFactory;
  
      public EntityManagerFactory getSessionFactory() {
          return sessionFactory;
      }
  }
  </code></pre>
  
  <p>The java stuff (The creation process):</p>
  
  <pre><code>public class CreateTest {
  
      // this is accessed by multiple threads to create new entities
      public static void crateNewEntityTest(String name) {
          EntityManagerFactory factory = DBHandler.get().getSessionFactory();
  
          EntityManager entityManager = factory.createEntityManager();
  
          entityManager.getTransaction().begin();
  
          EnTest newEnTest = new EnTest();
          newEnTest.setName(name);
  
          entityManager.persist(newEnTest);
  
          entityManager.getTransaction().commit();
          entityManager.close();
      }
  
         // The creation of threads and saving, this is just an example:
      public static void main(String[] args) {
          for (int i = 0; i &lt; 5; i++) {
              new Thread() {
                  public void run() {
                      CreateTest.createNewEntityTest("Name_" + i);
                  };
              }.start();
          }
      }
  }
  </code></pre>
  
  <p>The error:</p>
  
  <pre><code>Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
      at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1389)
      at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1317)
      at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:81)
      ... 2 more
  Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
      at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
      at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
      at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
      at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
      at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
      at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
      at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
      at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
      at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
      at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
      at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
      ... 2 more
  Caused by: java.sql.BatchUpdateException: Duplicate entry '3' for key 'PRIMARY'
      at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1666)
      at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1082)
      at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
      at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
      ... 10 more
  </code></pre>
  
  <p>The hibernate complains about the autoincrement of my Entity!</p>
  
  <p>What strategy should I take?</p>
  
  <p>Must I implement a Thread pool or something to handle the multiple threads entity saving?</p>
  
  <p>This thread issue wasn't to be a hibernate task?</p>