Search code examples
javaexceptioncollectionsconcurrentmodification

Why is a ConcurrentModificationException thrown and how to debug it


I am using a Collection (a HashMap used indirectly by the JPA, it so happens), but apparently randomly the code throws a ConcurrentModificationException. What is causing it and how do I fix this problem? By using some synchronization, perhaps?

Here is the full stack-trace:

Exception in thread "pool-1-thread-1" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
        at java.util.HashMap$ValueIterator.next(Unknown Source)
        at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:555)
        at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
        at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
        at org.hibernate.engine.Cascade.cascade(Cascade.java:130)

Solution

  • This is not a synchronization problem. This will occur if the underlying collection that is being iterated over is modified by anything other than the Iterator itself.

    Iterator it = map.entrySet().iterator();
    while (it.hasNext()) {
        Entry item = it.next();
        map.remove(item.getKey());
    }
    

    This will throw a ConcurrentModificationException when the it.hasNext() is called the second time.

    The correct approach would be

    Iterator it = map.entrySet().iterator();
    while (it.hasNext()) {
        Entry item = it.next();
        it.remove();
    }
    

    Assuming this iterator supports the remove() operation.