Search code examples
hibernatejvmout-of-memory

java.lang.OutOfMemoryError: Java heap space while updating the table in mysql


Trying to push/update large amount of collection into mysql using hibernate .My JVM heap size is 4GB still am facing OutOfMemoryError.Everything works fine when it call commit then error throws.

Note: I am new to hibernate.

Error :

Exception in thread "Thread-7" java.lang.OutOfMemoryError: Java heap space at java.base/java.util.Arrays.copyOf(Arrays.java:3745) at java.base/java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:172) at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:748) at java.base/java.lang.StringBuilder.append(StringBuilder.java:245) at com.mysql.cj.ClientPreparedQueryBindings.setString(ClientPreparedQueryBindings.java:651) at com.mysql.cj.jdbc.ClientPreparedStatement.setString(ClientPreparedStatement.java:1752) at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$1.doBind(VarcharTypeDescriptor.java:46) at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:73) at org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter$1.bind(AttributeConverterSqlTypeDescriptorAdapter.java:88) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:276) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:271) at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:39) at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:3073) at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:3048) at org.hibernate.persister.entity.AbstractEntityPersister$2.bindValues(AbstractEntityPersister.java:3271) at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3279) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3885) at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:84) at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645) at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282) at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263) at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317) at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330) at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287) at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:194) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:179) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:100) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:75) at org.hibernate.internal.SessionImpl$$Lambda$432/0x000000084074ac40.accept(Unknown Source)

Code:

public String addNewReport( int runId , Collection<ReportStorage> reportStorage )
    {
        int overAllCases = 0 ;
        int overAllPass  = 0 ;
        int overAllFail  = 0 ;
        try {
            if (isRunDetailExistsById(runId)) {
                
                HibernateConfig.getInstance().begin();
                RunDetails runDetails = HibernateConfig.getSession().get( RunDetails.class , runId);
                for( ReportStorage repStore : reportStorage )
                {
                    
                    repStore.setRun_id( runId );
                    repStore.getReportJson().setRun_id(runId);
                    overAllCases += repStore.getTotal_cases() ;
                    overAllPass  += repStore.getTotal_pass() ;
                    overAllFail  += repStore.getTotal_fail() ;
                }
                Collection<ReportStorage> existingReports = runDetails.getReports() ;
                existingReports.addAll( reportStorage ) ;
                runDetails.setReports( existingReports );
                runDetails.setEnd_time( CommonUtils.epocheTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())) );
                String timetaken = CommonUtils.timeConverter(runDetails.getEnd_time() - runDetails.getStart_time() ) ;
                runDetails.setOver_all_cases( Integer.toString(overAllCases ) );
                runDetails.setOver_all_pasess( Integer.toString( overAllPass ) );
                runDetails.setOver_all_failures( Integer.toString( overAllFail ) );
                runDetails.setTotal_time_taken( timetaken );
                runDetails.setRun_status("SUCCESS");
                
                HibernateConfig.getSession().saveOrUpdate(runDetails);
                HibernateConfig.getInstance().commit();
                
                HibernateConfig.close();
                return "SUCCESS" ;
        }else {
            return "Run Id Mismatch" ;
        }
        }
        catch (Exception e) {
            REPORTREPOLOGGER.info("addNewReport-"+ e.toString() );
            HibernateConfig.getInstance().rollback();
            HibernateConfig.close();
            throw new CustomException("addNewReport" , e)  ;
        }
        
    }

Solution

  • I guess your origin data runDetails is too large. when you execute saveOrUpdate function, it'll copy data first, but no more data memory left.

    Here is my suggestion:

    1. Try to increase the heap size of the JVM beyong the current 4GB if possible.
    2. Another option cloud be batch the inserts.