Search code examples
javamysqlperformanceopenjpa

OpenJPA merging/persisting is very slow


I use OpenJPA 2.2.0 on WebSphere Application Server 8 with a MySQL 5.0 DB.

I have a list of objects which I want to merge into the DB.

it's like:

for (Object ob : list) {
            Long start = Calendar.getInstance().getTimeInMillis();
            em = factory.createEntityManager();
            em.getTransaction().begin();

            em.merge(ob);

            em.getTransaction().commit();
            em.close();
            Long end = Calendar.getInstance().getTimeInMillis();
            Long diff = end - start;
            LOGGER.info("Time: " + diff);
        }

When I run this loop I need about 300-600 Milliseconds to merge one object. When I delete the line "em.merge(ob);" then I need "0" Milliseconds to iterate over 1 List Object.

So my question is: What can I do to improve the time to merge one object?

Thanks!


Solution

  • You can try starting the transaction before iteration & then commiting it afterwards within a single transaction. So, basically you are creating a batch which would be merged/persisted on commit.

    Also, you can limit the number of objects in a batch to be processed at a time & can explicitly flush the changes into database.

    Here, you are initiating a transaction & commiting it in each iteration and also creating/closing entity manager each time, will affect performance for numerous data.

    It will be something like below code.

    em = factory.createEntityManager();
    em.getTransaction().begin();
    int i = 0;
    
       for (Object ob : list) {
           Long start = Calendar.getInstance().getTimeInMillis();
    
           em.merge(ob);
    
           Long end = Calendar.getInstance().getTimeInMillis();
           Long diff = end - start;
           LOGGER.info("Time: " + diff);
    
           /*BATCH_SIZE is the number of entities 
                that will be persisted/merged at once */
    
           if(i%BATCH_SIZE == 0){    
               em.flush();
               em.clear(); 
           }
    
           i++;
       }
    
    em.getTransaction().commit();
    em.close();
    

    Here, you can also rollback the whole transaction if any of the object fails to persist/merge.