3

I need to do Bulk inserts(nearly 10000) in my MySQL database. I am using JPA/hibernate and spring boot. I read performing bulk insert/update in hibernate from hibernate documentation, I think my code is not working as it is sequentially inserting the hibernate queries instead of performing them in a batch insert. Below is my code. Am I missing something?

Here is my DataSource configuration.

@Component
public class Datasource {

    @Autowired 
    EnvConfiguration configuration;
    
    private static final Logger logger = LoggerFactory.getLogger(Datasource.class);
    
    @Bean
    public DataSource dataSource(){
        logger.info("DataSource Bean creation...");
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(configuration.getDBDriver());
        dataSource.setUrl("jdbc:mysql://"+configuration.getDBIp()+":"+configuration.getDBPort()+"/"+configuration.getDBName()+"?autoReconnect=true&useSSL=false");
        dataSource.setUsername(configuration.getDBUser());
        dataSource.setPassword(configuration.getDBPass().trim());
        return dataSource;
    }
    @Bean
    public HibernateJpaSessionFactoryBean sessionFactory() {
        return new HibernateJpaSessionFactoryBean();
    }
}

Code for my Role domain

//Role.java

    @Entity
    @Table(name = "Role",uniqueConstraints = @UniqueConstraint(
            columnNames = { "roleName"}))
    public class Role {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long roleId;
        @NotNull
        private String roleName;
        public Role(){}
    
        public Role(String roleName){
            this.roleName = roleName;
        }
    
        public Long getRoleId() {
            return roleId;
        }
    
        public void setRoleId(Long roleId) {
            this.roleId = roleId;
        }
    
        public String getRoleName() {
            return roleName;
        }
    
        public void setRoleName(String roleName) {
            this.roleName = roleName;
        }
    
    
    }

Below is my service code. Here I am manually flushing the session. I have added a sleep function in order to find whether insert query executed one by one or they are executing in batch of 10 as happen in JDBC batch.

@Service
public class RoleService{
    
    
    @Autowired
    private SessionFactory factory;
    
    @Autowired
    private DataSource source;

    private static final Logger logger =  LoggerFactory.getLogger(WalletService.class);


    public void insertRole(Collection<RegisterWallet> walletMetaCollection){

            if(factory==null){
                    System.out.println("factory is null");
                }else{
                    System.out.println("factory is working");
                    Session session = factory.openSession();
                    Transaction tx = session.beginTransaction();
        
                    for ( int i=0; i<100000; i++ ) {
                    Role role=new Role(""+i);
                    session.persist(role);
                System.out.println("this is the role id "+role.getRoleId());
   
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e){
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
   

 

            if ( i % 10 == 0 ) { //20, same as the JDBC batch size
  
                //flush a batch of inserts and release memory:
                    session.flush();
                    session.clear();
                }
            }
  

      
                    tx.commit();
                    session.close();
                }   
            }   
        }

As per my understanding over batch operation, 10 roles should be inserted at once, decreasing number of jdbc round trips used. But output of the above code is quiet unexpected. It is executing one insert per session.persist(..) call.

//This is log of the above code.


     Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 14
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 15
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 16
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 17
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 18
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 19
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 20
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 21
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 22
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 23
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 24
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 25
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 26
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 27
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 28
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 29
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 30
    Hibernate: insert into role (active, role_description, role_name) values (?, ?, ?)
    this is the role id 31
    </pre>

-------------------------------------------------------------

Following is my application.properties configuration

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
spring.jpa.properties.hibernate.jdbc.batch_size=10

Am I missing something?

Please help.

mghhrn
  • 38
  • 2
  • 6
Thinker
  • 518
  • 1
  • 6
  • 22

1 Answers1

0

You are't missing anything.Your output is quite normal.You can get more info on this link: [1]http://www.dineshonjava.com/2012/06/hibernate-batch-processing_10.html

  • Thanx Anzor for the reply, I read tutorial at the link posted by you, but even in that tutorial hibernate is inserting sequentially not it batch. But that link was helpful as it explain that in hiberate batch update is used for two thing for clearing the session cache and for executing similar sql query in batch. It was providing only the first functionality not the second . – Thinker Jul 26 '17 at 06:26
  • just try to add these two lines to your application properties file. spring.jpa.properties.hibernate.order_inserts=true spring.jpa.properties.hibernate.order_updates=true – anzor davarashvili Jul 26 '17 at 08:51
  • 2
    In Case someone is suffering from same issue, the solution is changing the generation type of primary key from Identity to Generation type table or manually adding the primary key through setter method, only then you will be able to get the benefits of batch inserts/update. – Thinker Aug 08 '17 at 05:40