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) ;
}
}
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: