-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: ConcurrentModificationException During Iteration Of Set
PostPosted: Tue Mar 23, 2004 4:37 pm 
Newbie

Joined: Fri Feb 27, 2004 11:44 pm
Posts: 8
In Hibernate version 2.1.2, is it a no-no to modify a set that is lazily loaded and cascaded using an Iterator? Here is my setup...

Class Foo has a set of Bars. The 'bars' set is lazily loaded and cascaded as shown below.

Code:
<hibernate-mapping>
    <class
        name="Foo"
        dynamic-update="false"
        dynamic-insert="false"
    >
        <set
            name="bars"
            lazy="true"
            inverse="true"
            cascade="all-delete-orphan"
        >
       
            <key
                column="foo_id"
            />

            <one-to-many
                class="Bar"
            />
        </set>
</hibernate-mapping>


If I run code like this:

Code:
Set bars = someFoo.getBars();
Iterator it = bars.iterator();
while (it.hasNext())
{
   Bar bar = (Bar)it.next();
   bars.remove(bar);
   session.delete(bar);
}


On the second pass through the loop the call to it.next() throws a ConcurrentModificationException. If I instead create a List from the set of bars and iterate through the list all works well. Shown below.

Code:
Set bars = someFoo.getBars();
List l = new ArrayList(bars);
for (int i=0; i<l.size(); i++)
{
   Bar bar = (Bar)l.get(i);
   bars.remove(bar);
   session.delete(bar);
}


Thanks,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 23, 2004 7:31 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Please read the JavaDoc for java.util.List and java.util.ArrayList


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 23, 2004 7:44 pm 
Regular
Regular

Joined: Mon Nov 24, 2003 6:36 pm
Posts: 105
in your loop, find the bar you want to remove (but do not remove), when found break out of loop. then do for.getBars().remove(foundBar)

You will need a working equals method too.


James


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 24, 2004 2:21 pm 
Newbie

Joined: Fri Feb 27, 2004 11:44 pm
Posts: 8
Yes, I'm aware of the work around and I know that the iterator is a fail-fast iterator. I was wanting to know if this was a bug or known behavior caused by hibernate mucking with the Set behind the scenes.

Thanks anyway,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 24, 2004 7:23 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
It is /nothing/ to do with Hibernate! In your second code example, were you to use an iterator instead of index iteration, you would get the same behavior. To safely remove from an iterating collection, you /must/ use Iterator.remove(). This is basic Java.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 24, 2004 7:32 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Actually, I was wrong, ArrayLists do not behave like this (you still shouldn't write that code, since the exception is allowed by the List interface). However, run this code:


Code:
   public void testStuff() throws Exception {
      HashSet list = new HashSet();
      list.add( new Object() );
      list.add( new Object() );
      Iterator iter = list.iterator();
      while ( iter.hasNext() ) list.remove( iter.next() );
   }


You will get a CME. The fix is to use this:

Code:
   public void testStuff() throws Exception {
      HashSet list = new HashSet();
      list.add( new Object() );
      list.add( new Object() );
      Iterator iter = list.iterator();
      while ( iter.hasNext() ) {
         iter.next();
         iter.remove();
      }      
   }


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 24, 2004 10:24 pm 
Newbie

Joined: Fri Feb 27, 2004 11:44 pm
Posts: 8
Got it! Sorry for taking up you bandwidth. An obvious oversight on my part. Thanks again.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.