db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tino Schöllhorn <t.schoellh...@plattform-gmbh.de>
Subject Bug and proposed patch
Date Sun, 12 Dec 2004 11:13:48 GMT
Hi,

yesterday I posted a problem in the user-list (Deleting Main-Object and 
its association-objects). Currently there are no answers for this 
message. I looked further at the code of OJB. The method which is 
interesting at this point is 
PersistenceBrokerImpl.deleteCollections(Object, List).

Suppose you have the following case: Persons work at Projects with an 
associated Role. Now if you are deleting a Person-Object or a 
Project-Object you want to delete the corresponding Role-objects as well.

Normally one can achieve that with *auto-delete=object* at the 
collections for the role-objects. But the current implementation does 
not work here correctly. If one has 3 or more role objects to be handled 
one gets a ConcurrentModificationException, like this one (line numbers 
have changed because of some change from me):

java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:448)
	at java.util.AbstractList$Itr.next(AbstractList.java:419)
	at 
org.apache.ojb.broker.core.PersistenceBrokerImpl.deleteCollections(PersistenceBrokerImpl.java:701)
	at 
org.apache.ojb.broker.core.PersistenceBrokerImpl.doDelete(PersistenceBrokerImpl.java:514)
	at 
org.apache.ojb.broker.core.PersistenceBrokerImpl.delete(PersistenceBrokerImpl.java:466)
	at 
org.apache.ojb.broker.core.DelegatingPersistenceBroker.delete(DelegatingPersistenceBroker.java:170)
	at 
org.apache.ojb.broker.core.DelegatingPersistenceBroker.delete(DelegatingPersistenceBroker.java:170)
	at kos.generator.DataObject.delete(DataObject.java:106)
	at kos.intranet2.sandbox.DeletePersonTest.runTest(DeletePersonTest.java:64)
	at kos.intranet2.sandbox.DeletePersonTest.main(DeletePersonTest.java:98)


The current implementation looks like:

if (cds.getCascadingDelete() == bjectReferenceDescriptor.CASCADE_OBJECT) 
{
	Object col = cds.getPersistentField().get(obj);
         if (col != null)
         {
         	while (colIterator.hasNext())
                 {
                 	doDelete(colIterator.next());
                 }
         }
}

And the ConcurrentModificationException is thrown at the call of doDelete.

If a am using OJB correctly this use-case should work. So I propose the 
following (but perhaps imperformant and inelegant) patch: The idea is 
simple. Instead of deleting the object immediately from its 
origin-collection, copy the elements to another collection an use this 
for deleting.

if (cds.getCascadingDelete() == bjectReferenceDescriptor.CASCADE_OBJECT) 
{
	Object col = cds.getPersistentField().get(obj);
         if (col != null)
         {
		// Inelegant and brutal. but it works
		 Collection c = new java.util.ArrayList();
                  while (colIterator.hasNext()) {
                  	c.add(colIterator.next());
                  }
                  Iterator j = c.iterator();
                  while (j.hasNext())
                  {
                  	doDelete(j.next());
                  }
         }
}

So do you think you could apply this patch - or am I mistaken and I am 
using OJB in a wrong way?

With regards
Tino






---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message