Twitter

marți, 26 iulie 2016

Hibernate batch processing with JpaRepository, JpaContext and PersistenceContext

As you can learn from How to batch INSERT and UPDATE statements with Hibernate (by Vlad Mihalcea), by default, Hibernate doesn't have the batch feature active. In order to activate it, just configure the hibernate.jdbc.batch_size property (e.g. between 5 and 30) as in the above article. For example, you can configure it depending on dialect bach size like this:

public static int batchSize() {
 return Integer.valueOf(Dialect.DEFAULT_BATCH_SIZE);
}

properties.put("hibernate.jdbc.batch_size", String.valueOf(batchSize()));  

Now, let's see three examples of Spring 4 MVC approaches that uses Hibernate batch for some inserts:

- Using JpaRepository:

public interface ProductRepository extends JpaRepository<Product, Long> {
 // NOPE
}

And ...

@Autowired
private ProductRepository productRepository;
...
@Override      
@Transactional
public void withBatching(int n) {

 // preparing the products
 ArrayList<Product> productsInBatch = new ArrayList<>();
 for (int i = 0; i < n; i++) {
      Product p = new Product(i);
      productsInBatch.add(p);
 }                

 long start = System.nanoTime();

 // persist via batching
 productRepository.save(productsInBatch);

 LOG.log(Level.INFO, "INSERTED {0} PRODUCTS IN: {1} MILISECONDS.",
         new Object[]{n, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)});        
}

The complete example is available here.

- Using JpaContext:

@Autowired
private JpaContext jpaContext;
...
@Override
@Transactional
public void withBatching(int n) {

 EntityManager em = jpaContext.getEntityManagerByManagedType(Product.class);

 long start = System.nanoTime();
 int batchSize = ...;

 // persist via batching        
 for (int i = 0; i < n; i++) {
      Product p = new Product(i);
      em.persist(p);

      // Flush a batch of inserts and release memory
      if (i % batchSize == 0 && i > 0) {
          em.flush();
          em.clear();
      }
  }
  
  LOG.log(Level.INFO, "INSERTED {0} PRODUCTS IN: {1} MILISECONDS.",
          new Object[]{n, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)});
}

The complete example is available here.

- Using PersistenceContext:

@PersistenceContext
private EntityManager entityManager;

And ...
@Autowired
private ProductDAO productDAO;

 @Override
 @Transactional
 public void withBatching(int n) {

  long start = System.nanoTime();

  // persist via batching    
  productDAO.persistWithBatching(n);

  LOG.log(Level.INFO, "INSERTED {0} PRODUCTS IN: {1} MILISECONDS.",
          new Object[]{n, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)});
}

The complete example is available here.

For a batch size of 15, in all examples you should get an output as below:

2 comentarii:

  1. nice article.....

    Eglobalsystems Offering Advanced Java Real-time Online Training Classes For Weekend And Regular Batches For Individuals And Professionals. Eglobalsystems Offering Free DEMO/ Seminar On Advanced Java Access Control By Real Time Expert. Once Experience Our Free Sessions And Decide Further.
    Eglobalsystems providing Best Advanced Java Online Training in Hyderabad, India, Pune, Chennai, Mumbai, banglore, USA, UK, Australia, New Zealand, UAE, Saudi Arabia,Pakistan, Singapore, Kuwait.

    RăspundețiȘtergere
  2. It's interesting that many of the bloggers to helped clarify a few things for me as well as giving.Most of ideas can be nice content.The people to give them a good shake to get your point and across the command.
    Java Training in Chennai

    RăspundețiȘtergere