From bed35de926d0fe53c207b2fea7f5e3d1922d0ddb Mon Sep 17 00:00:00 2001 From: rgurley Date: Wed, 13 Jun 2012 14:24:13 -0700 Subject: [PATCH] Attempt to fix issues with disappearing snapshots when using nested editing contexts. --- .../Sources/er/extensions/eof/ERXEC.java | 27 ++++++++++++++++++- .../Sources/er/extensions/eof/ERXECTest.java | 25 +++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/eof/ERXEC.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/eof/ERXEC.java index f891d5c4cad..2767d7a3b9a 100644 --- a/Frameworks/Core/ERExtensions/Sources/er/extensions/eof/ERXEC.java +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/eof/ERXEC.java @@ -172,6 +172,9 @@ public class ERXEC extends EOEditingContext { private static final NSSelector EditingContextWillRevertObjectsDelegateSelector = new NSSelector("editingContextWillRevertObjects", new Class[] { EOEditingContext.class, NSArray.class, NSArray.class, NSArray.class }); private static final NSSelector EditingContextDidRevertObjectsDelegateSelector = new NSSelector("editingContextDidRevertObjects", new Class[] { EOEditingContext.class, NSArray.class, NSArray.class, NSArray.class }); private static final NSSelector EditingContextDidFailSaveChangesDelegateSelector = new NSSelector("editingContextDidFailSaveChanges", new Class[] { EOEditingContext.class, EOGeneralAdaptorException.class }); + + private static final String ERXECProcessQueuedNotificationsNotification = "processQueuedNotifications"; + public static final NSSelector ERXECProcessQueuedNotificationsSelector = ERXSelectorUtilities.notificationSelector("processQueuedNotificationsNotification"); /** * @return the value of the er.extensions.ERXEC.editingContextClassName property, which @@ -1484,7 +1487,20 @@ public Object invokeRemoteMethod(EOEditingContext eoeditingcontext, EOGlobalID e @Override public void _objectsChangedInStore(NSNotification nsnotification) { ERXEnterpriseObject.FlushCachesProcessor.perform(this, (NSArray) nsnotification.userInfo().objectForKey("objects")); - if (savingChanges) { + + /* + * Check to see if this context, or any parent context, is saving changes. + * If so, queue up the notifications. + */ + boolean isSavingChanges = savingChanges; + EOObjectStore parent = parentObjectStore(); + while(!isSavingChanges && parent instanceof ERXEC) { + ERXEC parentEc = (ERXEC) parent; + isSavingChanges = parentEc.savingChanges; + parent = parentEc.parentObjectStore(); + } + + if (isSavingChanges) { synchronized (queuedNotifications) { queuedNotifications.addObject(nsnotification); } @@ -1567,6 +1583,11 @@ private void processQueuedNotifications() { for (NSNotification notification : queuedNotificationsClone) { _objectsChangedInStore(notification); } + NSNotificationCenter.defaultCenter().postNotification(ERXECProcessQueuedNotificationsNotification, this); + } + + public void processQueuedNotificationsNotification(NSNotification n) { + processQueuedNotifications(); } /** @@ -1732,6 +1753,10 @@ public EOEditingContext _newEditingContext(EOObjectStore objectStore, boolean va ec.unlock(); } NSNotificationCenter.defaultCenter().postNotification(EditingContextDidCreateNotification, ec); + if(objectStore instanceof ERXEC) { + ERXEC parent = (ERXEC)objectStore; + NSNotificationCenter.defaultCenter().addObserver(ec, ERXECProcessQueuedNotificationsSelector, ERXECProcessQueuedNotificationsNotification, parent); + } return ec; } diff --git a/Tests/ERXTest/Sources/er/extensions/eof/ERXECTest.java b/Tests/ERXTest/Sources/er/extensions/eof/ERXECTest.java index f69466ffdaf..6ec59ffaea2 100644 --- a/Tests/ERXTest/Sources/er/extensions/eof/ERXECTest.java +++ b/Tests/ERXTest/Sources/er/extensions/eof/ERXECTest.java @@ -18,6 +18,7 @@ import er.erxtest.ERXTestCase; import er.erxtest.ERXTestUtilities; import er.erxtest.model.Company; +import er.erxtest.model.Employee; public class ERXECTest extends ERXTestCase { @@ -52,6 +53,30 @@ public void testConstructorWithObjectStore() { Assert.assertEquals(parentEC3, ec3.parentObjectStore()); } + 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()); + } + } + public void testSerializablilty() throws IOException, ClassNotFoundException { EOEditingContext ec = ERXEC.newEditingContext(); Company.createCompany(ec, "Some fruit company");