hakansander
hakansander

Reputation: 377

Define different batch sizes in spring data jpa for different repositories

I have 2 different repositories in the same Spring Boot project.

I would like to define different batch sizes for the 2 different repositories. However, I could not find any solution for Spring Data Jpa config.

The repositories are given below:

@Repository
public interface ItemRepository extends JpaRepository<Item, String> {
   Page<Item> findItemByCreationDateBefore(Timestamp creationDate, Pageable pageable);
}


@Repository
public interface CarRepository extends JpaRepository<Car, String> {
   @Query("SELECT c FROM Car c WHERE c.journeyCode = :journeyCode " +
          "AND c.currentLocationId = :currentLocationId")
   Page<Delivery> findCars(Long journeyCode, Long currentLocationId, Pageable pageable);
}

The batch size configuration is given below

    jpg:
      spring:
        properties:
          hibernate:
            jdbc:
              batch_size: 4
            order_inserts: true
            order_updates: true

Is it possible configuring the batch sizes that way? If it is possible, how can I implement this?

Upvotes: 3

Views: 7733

Answers (1)

SternK
SternK

Reputation: 13041

Theoretically you can try to implement BatchBuilder interface for example in the following way:

import java.util.Map;

import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.engine.jdbc.batch.internal.BatchBuilderMXBean;
import org.hibernate.engine.jdbc.batch.internal.BatchingBatch;
import org.hibernate.engine.jdbc.batch.spi.Batch;
import org.hibernate.engine.jdbc.batch.spi.BatchBuilder;
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.Manageable;


public class MyBatchBuilder implements BatchBuilder, Configurable, Manageable, BatchBuilderMXBean
{
   private int jdbcBatchSize;
   
   public MyBatchBuilder()
   {
   }
   
   public MyBatchBuilder(int jdbcBatchSize) {
      this.jdbcBatchSize = jdbcBatchSize;
   }

   @Override
   public void configure(Map configurationValues) {
      jdbcBatchSize = ConfigurationHelper.getInt( Environment.STATEMENT_BATCH_SIZE, configurationValues, jdbcBatchSize );
   }

   @Override
   public int getJdbcBatchSize() {
      return jdbcBatchSize;
   }

   @Override
   public void setJdbcBatchSize(int jdbcBatchSize) {
      this.jdbcBatchSize = jdbcBatchSize;
   }
   
   @Override
   public Batch buildBatch(BatchKey key, JdbcCoordinator jdbcCoordinator)
   {
      final Integer sessionJdbcBatchSize = jdbcCoordinator.getJdbcSessionOwner()
            .getJdbcBatchSize();
      final int jdbcBatchSizeToUse = sessionJdbcBatchSize == null ?
            this.jdbcBatchSize :
            sessionJdbcBatchSize;

      // getEntityName() + "#DELETE"
      // getEntityName() + "#UPDATE"
      BasicBatchKey insertCarBatchKey = new BasicBatchKey("com.your.entities.Car#INSERT", null);
      final int jdbcBatchSizeForCar = 20;
      if (insertCarBatchKey.equals(key))
      {
         return new BatchingBatch( key, jdbcCoordinator, jdbcBatchSizeForCar );
      }

      return new BatchingBatch( key, jdbcCoordinator, jdbcBatchSizeToUse );
   }
}

and then add the following properties to your spring application config:

spring.jpa.properties.hibernate.jdbc.batch.builder=com.your.app.MyBatchBuilder
spring.jpa.properties.hibernate.jdbc.batch_size=4

But as it's stated in the hibernate documentation, it is almost never a good idea to switch from Hibernate’s default implementation. So, maybe suggested in the comment approach will be more preferable for your needs.

P.S. Also as it's stated in the hibernate documentation:

Since version 5.2, Hibernate allows overriding the global JDBC batch size given by the hibernate.jdbc.batch_size configuration property on a per Session basis.

entityManager
    .unwrap( Session.class )
    .setJdbcBatchSize( 10 );

Upvotes: 3

Related Questions