Tuesday 11 May 2010

ConcurrentModificationException occurred

Recently had a ConcurrentModificationException in a single threaded piece of code. That was weird. Luckily there are lots of resources (google is your friend) that tell you how to solve it.

Here's the offending piece of code.

Set<Orders> ordersToDelete = customer.getOrders();
        
for(Order order : ordersToDelete)
{
    order.setCustomer(null);
    customer.getOrders().remove(order);
    order.setCompany(null);
    genericCustomDAO.remove(order);
}
I thought about just "nulling" the Set in Customer, but that is not possible as hibernate wants to have references removed before attempting to remove the object itself. (yeah, I should look into the whole CascaseType.ALL thing sometime.)

The ugliest thing that you could do is of course make a copy of the set and then iterate over this new set, removing the items in the old set.

Now, if we only had access to the nice Iterator that the foreach loop above uses, things would be fine. But we do not, so it is time to grasp back to the ancient days where we had to write our own for-loops.

Iterator<Order> ordersToDelete = 
    customer.getOrders().iterator();
        
while (ordersToDelete.hasNext())
{
    Order order = ordersToDelete.next();
    order.setCustomer(null);
    // remove the item from the set by using the
    // remove method of the iterator
    order.setMeasure(null);
    ordersToDelete.remove();
    genericCustomDAO.remove(order);
}
Calling the remove on the iterator itself solves the problem for me.