Concurrent Modification exception while evicting cache in Hibernate

My application maintains a cache of list of users and it is evicted when any new user is created.
I am getting Concurrent Modification exception while evicting the cache.

Stack trace :

java.util.ConcurrentModificationException: null
 	at java.util.HashMap.forEach(HashMap.java:1292)
    at org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl.releaseResources(ResourceRegistryStandardImpl.java:323)
	at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.afterTransaction(AbstractLogicalConnectionImplementor.java:60)
	at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.afterTransaction(LogicalConnectionManagedImpl.java:167)
	at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.afterCompletion(LogicalConnectionManagedImpl.java:291)
	at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.commit(AbstractLogicalConnectionImplementor.java:95)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:282)
	at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
	at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:627)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:633)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:386)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
	at com.mytestapp.service.impl.MyCacheManager$$EnhancerBySpringCGLIB$$6a5d7f13.resetTeamListCache(<generated>)
	at 
com.mytestapp.webapp.listener.StartupListener.refreshContext(StartupListener.java:199)
	at com.mytestapp..webapp.controller.admin.SystemUserManagementController.saveSystemUserData(SystemUserManagementController.java:529)

In my controller the code is as follows :

systemUserProfileManager.saveSystemUserProfile(userBasicInfo); // async call
StartupListener.refreshContext(request.getSession().getServletContext()); // cache evict

refreshContextMethod in StartupListener :

public static void refreshContext(ServletContext context) {
		ApplicationContext ctx = WebApplicationContextUtils
				.getRequiredWebApplicationContext(context);
		MyCacheManager myCacheManager = (MyCacheManager) ctx
				.getBean(myCacheManager);
		
		LOG.debug("Processing started for refreshing Servlet Context/ Cache!");
		// RESET All Cache
		myCacheManager.resetTeamListCache();
		LOG.debug("Processing completed for refreshing Servlet Context/ Cache!");
	}

resetTeamListCache method in MyCacheManager :

@CacheEvict(value = CacheConstants.SALES_TEAM_LIST, allEntries = true)
public void resetTeamListCache() {
    // Intentionally blank
}

You can’t use a Hibernate Session across multiple threads, so whatever async you do, that’s not going to work. Every threads needs a separate Session.

1 Like

I use getCurrentSession to obtain the session object . Since async call is executed in a separate thread , it will create a new session object. Right ?

Usually, yes, but it seems the error you are seeing might be related to concurrency issues.