I think I've narrowed this down a bit :-) If I add
NSNotificationCenter nc = NSNotificationCenter.defaultCenter(); nc.removeObserver(nested, EOObjectStore.ObjectsChangedInStoreNotification, null);
Just before the last ec.saveChanges(), the save is successful. Looking in ERXEC, I see
/** * Overridden so add a bugfix from Lenny Marks */ @Override public void _objectsChangedInStore(NSNotification nsnotification) { ERXEnterpriseObject.FlushCachesProcessor.perform(this, (NSArray) nsnotification.userInfo().objectForKey("objects")); if (savingChanges) { synchronized (queuedNotifications) { queuedNotifications.addObject(nsnotification); } } else { super._objectsChangedInStore(nsnotification); } }
For background, here's the original thread from Lenny Marks
So it would seem that the nested ECs are sneaking past this fix and causing havoc. I'm still not sure what about garbage collection triggers this, but I've updated ERXEC so that nested ECs check to see if any of its parents are saving before processing notifications. The test passes with that change in place.
I've got it up on the SmartHealth fork of wonder. If you guys are interested, then give it a try and see if it works for you. There doesn't appear to be any testing of nested ECs that I can see in ERXTest, but I don't think this will have any negative consequences.
I'm deploying this out to a dev server now to see if any more snapshots go missing. If all goes well, I'll pull this change into the main wonder fork.
Ramsey
On Jun 12, 2012, at 2:22 PM, Alexis Tual wrote: I'm also very curious about Ramsey's investigations because when this bug happens, you have to basically toss your EC stack...
Alex
2012/6/13 Calven Eggert <email@hidden>
I'm very curious to see your findings. One of our WO apps have had this problem for years but it happens so infrequently that the users don't seem to be bothered. It bothers me though. argh.
Ah, so it's the garbage collection that's triggering it. I should have known, given the looping worked for small values. This is good. I can distill the failure down to a single pair of EOs using System.gc() now. This should make it a lot easier to investigate.
public void testNestedECs() {
try {
EOEditingContext ec = ERXEC.newEditingContext();
Company c = (Company) EOUtilities.createAndInsertInstance(ec, Company.ENTITY_NAME);
c.setName("Name");
ec.saveChanges(); EOEditingContext nested = ERXEC.newEditingContext(ec);
Company nestC = c.localInstanceIn(nested);
Employee e = (Employee) EOUtilities.createAndInsertInstance(nested, Employee.ENTITY_NAME);
e.setFirstName("First");
e.setLastName("Last");
e.setManager(Boolean.FALSE);
e.addObjectToBothSidesOfRelationshipWithKey(nestC, Employee.COMPANY_KEY);
nested.saveChanges();
ec.saveChanges(); System.gc();
c.delete();
ec.saveChanges(); } catch (Exception e) {
e.printStackTrace();
Assert.fail(e.getMessage()); }
}
Thanks Alexis,
Ramsey
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
|