You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by sclark <sc...@detox.tat.fws.gov> on 2003/08/01 17:54:11 UTC

Resubmit: PATCH: Can't recreate previously deleted object

It appears that this problem still exists in rc4.  The problem is that if I 
delete an object and then in a later ODMG transaction try to create another 
object with the same Identity, the new object is never written to the database.  
I propose two alternate fixes below.

Will this be fixed before 1.0?

-steve

------------- Begin Forwarded Message -------------

List-Id: "OJB Users List" <ojb-user.db.apache.org>
Date: Wed, 25 Jun 2003 13:26:03 -0600 (MDT)
From: sclark <sc...@euler.cr.usgs.gov>
Subject: PATCH: Can't recreate previously deleted object
To: ojb-user@db.apache.org
Content-MD5: pGtE5jUeDVw0fi0FZ/AkOA==

I am using rc3, ODMG.

I have encountered the following incorrect behavior:

   tx {
     Retrieve Role{1}
   }
   tx {
     Delete Role{1}
     role = new Role{2}
     lock role
   }
   tx {
     Delete Role{2}
     role = new Role{1}
     lock role
   }

Role{1} is not inserted into the db in the final transaction.  According to the
log, Role{1} gets registered with StateOldClean, which is incorrect.

Here is my analysis:

  (1) ObjectEnvelope.setInitialModificationState() has this code:

        if (LoadedObjectsRegistry.isRegistered(myObj))
        {
            initialState = 
org.apache.ojb.odmg.states.StateOldClean.getInstance();
        }

      That is, when an object is registered with a tx, if it has been seen 
before
      then it is always registered as StateOldClean.  I think that theoretically
      "seen before" means "seen in a currently running PB transaction", but I'm 
not
      certain of this.

  (2) LoadedObjectsRegistry has the following comment:

        Note: objects remain registered even after they are deleted. This
        is necessary to prevent creation of deleted objects by another
        thread, see <a 
href="http://archives.apache.org/eyebrowse/ReadMsg?listId=106&msgNo=1382">this<a
>
        for details.

      Because the list archives are broken, I can't read that thread to see what
      the  problem was or the reasoning about the solution.

  (3) PersistenceBrokerImpl.delete() calls objectCache.remove(), rather than
      this.removeFromCache().  This has the effect described in (2), i.e., the
      deleted object is removed from the cache but not from 
LoadedObjectsRegistry.

  (4) After calling broker.delete(), StateOldDelete.commit() calls
      broker.removeFromCache().  The latter call looks up the oid in the cache 
and
      then removes the object it finds from LoadedObjectsRegistry.  Because 
delete()
      has already removed the object from the cache, 
LoadedObjectsRegistry.remove()
      is called with null, and the object stays in the LOR forever.

As a result, it will never be possible to recreate the object in question.

I have fixed the problem by replacing

             objectCache.remove(new Identity(obj, this, cld));

with

             removeFromCache(new Identity(obj, this, cld));

in PersistenceBrokerImpl.delete().  But I think that this probably breaks the 
issue
mentioned in the LoadedObjectsRegistry comment.  Perhaps somebody who 
understands
that issue could look into this bug?

An alternative fix, which seems somewhat less robust but won't trip over the 
issue
in (2), is for PersistenceBrokerImpl.removeFromCache() not to rely on the object
being in the cache in order to remove it from the LOR unless it has to.  Here is 
a
patch implementing this solution:

    public void removeFromCache(Object obj) throws PersistenceBrokerException
    {
    	// objects must also be remove from LoadedObjectsRegistry
    	// Fix by Jamie Burns
        Identity identity;
	Object objectToRemove;
        if (obj instanceof Identity)
        {
            identity = (Identity)obj;
	    objectToRemove = objectCache.lookup(identity);
        }
        else
        {
            identity = new Identity(obj, this);
	    objectToRemove = obj;
        }
        LoadedObjectsRegistry.remove(objectToRemove);
        objectCache.remove(identity);
    }

Can somebody please apply one or the other (or yet another, if that is 
appropriate)
patch to CVS?

thanks,
-steve

Steve Clark
Technology Applications Team
Natural Resources Research Center/USGS
sclark@detox.cr.usgs.gov
(970)226-9291


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


------------- End Forwarded Message -------------



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