13/04/2018

Batch processing in Hibernate – Java’s ORM

Developers are often facing the problem of inserting large data, so this article could help them to
see the ways how to do it in proper way in order to avoid common-mistakes.

 

This is the way how batch processing shouldn’t be done:

public void insertBatch(List entities){
EntityManager em = DatabaseProvider.getEntityManager();
EntityTransaction transaction = em.getTransaction();

try {
transaction.begin();
for (int i = 0; i < entities.size(); i++){
em.persist(entities.get(i));
}
transaction.commit();
} catch (Exception ex){
ex.printStackTrace();
transaction.rollback();
}
}

 

There are several reasons why we should not use this approach:

  1. In case of large collection of entities – e.g. 1 million? This can cause the OutOfMemory error in the persistence context and we have not persisted anything in the database.
  2. Long-running operation which reserves one connection.
  3. In case that we need at least some of the information to be stored, this will not fit our expectations. In case of a failure, none of the records will be inserted.

 

So, the better approach would be:

public void batchInsertOneTransaction(List entities){
EntityManager entityManager = DatabaseProvider.getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
for (int i = 0; i < entities.size(); i++){ entityManager.persist(entities.get(i)); if (i > 0 && i % 50 == 0){
entityManager.flush();
entityManager.clear();
}
}
transaction.commit();
} catch (Exception ex){
transaction.rollback();
ex.printStackTrace();
}
}

 

The reasons why this is a better approach are:

  1. Out of memory cannot happen because we clear our persistence context after we flush the data into database.
  2. This approach will save all the data, but in case of a failure, it will not save any data.

 

Another solution would contain more transactions:

public void batchInsertMultiTransaction(List entities){
EntityManager entityManager = DatabaseProvider.getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
for (int i = 0; i < entities.size(); i++){ try { entityManager.persist(entities.get(i)); if (i > 0 && i % 50 == 0){
entityManager.flush();
entityManager.clear();
transaction.commit();
transaction.begin();
}
} catch (Exception ex){
transaction.rollback();
ex.printStackTrace();
}
}
} finally {
//if the number of entities is not divisable by 50
try {
entityManager.flush();
entityManager.clear();
transaction.commit();
} catch (Exception ex){
transaction.rollback();
ex.printStackTrace();
}
}
}

 

Advantage:

  1. In case of a failure, this approach will store some of the data which should be taken with awareness. In case that we need the exact order of the data, or if all data needs to be stored, or the application depends on the accumulation field, this has to be done with the previous algorithm.
  2. Beside that, with this approach you can mark the failed data and after cleaning them you can insert it again

 

Further:

When it comes to performance, if it’s low, writing native SQL is always a good option, but there is one requirement we need to fulfill.
You have to add the parameter “?rewriteBatchedStatements=true” to the connection url. The connection url will look like
jdbc:mysql://localhost:3306/simple_task_batch?rewriteBatchedStatements=true

Let’s assume that we have a specific entity Person.
This will produce the batch insert to be like

INSERT INTO person (first_name,last_name) VALUES ("FIRST NAME 1", "LAST NAME 1"), ("FIRST NAME 2", "LAST NAME 2"), ("FIRST NAME 3", "LAST NAME 3")...

Instead of:

INSERT INTO person (first_name,last_name) VALUES ("FIRST NAME 1", "LAST NAME 1");
INSERT INTO person (first_name,last_name) VALUES ("FIRST NAME 2", "LAST NAME 2");
INSERT INTO person (first_name,last_name) VALUES ("FIRST NAME 3", "LAST NAME 3");

 

And the method will look like this (with batch size e.g. 100000):

public void batchInsertNative(List entities){
Connection connection = DatabaseProvider.getConnection();

try {
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO person (first_name,last_name) VALUES (?,?)");;
for (int i = 0; i < entities.size(); i++){
try {
preparedStatement.setString(1,entities.get(i).getFirstName());
preparedStatement.setString(2,entities.get(i).getLastName());
preparedStatement.addBatch();
if (i % 100000 == 0){
preparedStatement.executeBatch();
connection.commit();
}
} catch (Exception ex){
ex.printStackTrace();
connection.rollback();
}
}

//if the number of entities is not divisable by 100000
preparedStatement.executeBatch();
connection.commit();
connection.close();
} catch (Exception e){
e.printStackTrace();
}
}

 

To conclude, we will repeat one more time, this approach is the same as the example batchInsertMultiTransaction, but this time it’s written in native SQL,
so it will save some of the data in case of failure. But also, it depends on what do you want to achieve – either save all the data, just the part of them or none.

We are looking for a Senior Blockchain Developer with 5+ years of experience who will join our team.

Your core skills are:

  • Proven experience as a Blockchain Developer, with a strong focus on JavaScript
  • Proficiency in JavaScript, including frameworks such as Node.js, React, or Angular
  • Solid understanding of blockchain concepts and cryptographic principles
  • Experience with smart contract development and deployment on platforms like Ethereum or Hyperledger
  • Extensive knowledge of Object-Oriented Programming (OOP), including principles, data structures, algorithms, and design patterns
  • Familiarity with Docker, Kubernetes, and cloud services to support modern application development and deployment
  • Demonstrable experience with software engineering tools such as Git for version control, Maven for build automation, and tools for unit and integration testing
  • Comfortable working within a Scrum Agile framework to deliver high-quality software in iterative cycles

Requirements:

  • Minimum of 5 years of relevant experience
  • Degree in Computer Science or a related field
  • Proficiency in English with excellent communication skills
  • Strong problem-solving and analytical abilities
  • Effective communication and presentation skills

What We Offer:

  • Remote work opportunities with flexible hours
  • No overtime policy
  • 25 vacation days annually to recharge and relax
  • Challenging international projects to expand your horizons
  • Private health insurance including regular medical check-ups
  • Supportive and friendly work environment that values honesty
  • Knowledge-sharing, transparent, and proactive communication within the team

If you’re ready to take on exciting challenges and grow your career with a supportive and innovative team, we’d love to hear from you!

    We are looking for a Senior Full Stack Developer with 5+ years of experience who will join our team.

    Your core skills are:

    • Excellent knowledge of Java and JavaScript programming language
    • Excellent knowledge of Spring, Spring Boot, Hibernate
    • Excellent knowledge of Angular or React
    • Proficiency in both relational (e.g., MySQL, PostgreSQL) and NoSQL databases (e.g., MongoDB)
    • Good understanding of Microservice architecture
    • Exposure to Docker, Kubernetes, and cloud services is beneficial (AWS or Azure)
    • Extensive OOP knowledge - principles, data structures, algorithms, and patterns
    • Demonstrable experience building modern software using engineering tools such as Git, Maven, unit testing, and integration testing tools
    • Experience working in Scrum Agile methodology

    Requirements:

    • A minimum of 5 years of relevant experience
    • Degree in Computer Science or other relevant field
    • Excellent verbal and written communication skills in English
    • Strong problem-solving and analytical skills
    • Effective communication and presentation skills (written and verbal)

    We can give you a fair amount of great benefits such as:

    • Remote work opportunities with flexible hours
    • No overtime policy
    • 25 vacation days annually to recharge and relax
    • Challenging international projects to expand your horizons
    • Private health insurance including regular medical check-ups
    • Supportive and friendly work environment that values honesty
    • Knowledge-sharing, transparent, and proactive communication within the team

    Feel free to apply for the job if you think we are a perfect match!

      We are looking for a Senior iOS Developer with 5+ years of experience who will join our team.

      Your core skills are:

      • Excellent knowledge of iOS SDK (Objective-C and Swift) and XCode
      • Extensive OOP knowledge - principles, data structures, algorithms, and patterns
      • Demonstrable experience building modern software using engineering tools such as Git, Maven, unit testing, and integration testing tools
      • Experience working in Scrum Agile methodology
      • It would be beneficial to have experience with Android and Flutter

      Requirements:

      • A minimum of 5 years of relevant experience
      • Degree in Computer Science or other relevant field
      • Excellent verbal and written communication skills in English
      • Strong problem-solving and analytical skills
      • Effective communication and presentation skills (written and verbal)

      We can give you a fair amount of great benefits such as:

      • Remote work opportunities with flexible hours
      • No overtime policy
      • 25 vacation days annually to recharge and relax
      • Challenging international projects to expand your horizons
      • Private health insurance including regular medical check-ups
      • Supportive and friendly work environment that values honesty
      • Knowledge-sharing, transparent, and proactive communication within the team

      Feel free to apply for the job if you think we are a perfect match!

        We are looking for a Senior .NET Developer with 5+ years of experience who will join our team.

        Your core skills are:

        • Excellent knowledge of .NET (.NET Core and ASP.NET)
        • Excellent knowledge of SQL server
        • Good knowledge of JavaScript and frameworks such as React and Angular
        • Good understanding of Microservice architecture
        • Extensive OOP knowledge - principles, data structures, algorithms, and patterns
        • Exposure to Docker, Kubernetes, and cloud services is beneficial
        • Demonstrable experience building modern software using engineering tools such as Git, Maven, unit testing, and integration testing tools
        • Experience working in Scrum Agile methodology

        Requirements:

        • A minimum of 5 years of relevant experience
        • Degree in Computer Science or other relevant field
        • Excellent verbal and written communication skills in English
        • Strong problem-solving and analytical skills
        • Effective communication and presentation skills (written and verbal)

        We can give you a fair amount of great benefits such as:

        • Remote work opportunities with flexible hours
        • No overtime policy
        • 25 vacation days annually to recharge and relax
        • Challenging international projects to expand your horizons
        • Private health insurance including regular medical check-ups
        • Supportive and friendly work environment that values honesty
        • Knowledge-sharing, transparent, and proactive communication within the team

        Feel free to apply for the job if you think we are a perfect match!