Issue
I have extended the EmptyInterceptor
provided by hibernate to perform some logic on post flush. The overwritten post flush method is provided with an iterator. When I tried to iterate, I received ConcurrentModificationException
.
@Override
public void postFlush(Iterator entities) throws CallbackException
{
while (entities.hasNext())
{
Object entity;
try
{
entity = entities.next();
}
catch(ConcurrentModificationException e)
{
// I get concurrent modification exception while iterating.
return;
}
}
}
I am getting the below exception,
java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(HashMap.java:922) at java.util.HashMap$ValueIterator.next(HashMap.java:950) at org.hibernate.internal.util.collections.LazyIterator.next(LazyIterator.java:51) at com.mycompany.MyInterceptor.postFlush(MyInterceptor.java:55) at org.hibernate.event.internal.AbstractFlushingEventListener.postPostFlush(AbstractFlushingEventListener.java:401) at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:70) at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1130) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1580) at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
From Hibernate Forum we can understand that the iterator passed to the postFlush() method is not thread safe causing ConcurrentModificationException.
Suggestions and solution to avoid the exception is appreciated.
Solution
Copying iterator into a list via org.apache.commons.collections.IteratorUtils before iterating worked for me :
@Override
public void preFlush(Iterator entities) {
List list= IteratorUtils.toList(entities);
for(Object o : list){...}
}
However i can't explain why it is working when using IteratorUtils...
Answered By - NzoP
Answer Checked By - Mary Flores (JavaFixing Volunteer)