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)
Advertisement
Answer
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.