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 [EMAIL PROTECTED] (970)226-9291 --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]