From c3df0c7cf3a15cce7067cbb0eecf35137091f1a3 Mon Sep 17 00:00:00 2001 From: Fabian Peters Date: Wed, 6 Jan 2016 13:21:05 +0100 Subject: [PATCH] Fix handling of owned relationships in ERMDDeleteButton. The previous implementation would cause an NPE in EOEditingContext.initializeObject() when saving the nested EC, since the related object was already marked as deleted in the parent EC, due to it being removed from its owner. --- .../components/buttons/ERMDDeleteButton.java | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Frameworks/D2W/ERModernDirectToWeb/Sources/er/modern/directtoweb/components/buttons/ERMDDeleteButton.java b/Frameworks/D2W/ERModernDirectToWeb/Sources/er/modern/directtoweb/components/buttons/ERMDDeleteButton.java index 9c880fa2904..22df0b58fe7 100644 --- a/Frameworks/D2W/ERModernDirectToWeb/Sources/er/modern/directtoweb/components/buttons/ERMDDeleteButton.java +++ b/Frameworks/D2W/ERModernDirectToWeb/Sources/er/modern/directtoweb/components/buttons/ERMDDeleteButton.java @@ -11,6 +11,8 @@ import com.webobjects.directtoweb.ConfirmPageInterface; import com.webobjects.directtoweb.D2W; import com.webobjects.directtoweb.D2WPage; +import com.webobjects.eocontrol.EOClassDescription; +import com.webobjects.eocontrol.EODataSource; import com.webobjects.eocontrol.EODetailDataSource; import com.webobjects.eocontrol.EOEditingContext; import com.webobjects.eocontrol.EOEnterpriseObject; @@ -45,7 +47,9 @@ */ public class ERMDDeleteButton extends ERMDActionButton { - @SuppressWarnings("unused") + private static final long serialVersionUID = 1L; + + @SuppressWarnings("unused") private static final Logger log = Logger.getLogger(ERMDDeleteButton.class); public final static String DisplayGroupObjectDeleted = "DisplayGroupObjectDeleted"; @@ -113,12 +117,32 @@ public WOActionResults deleteAction() { * in-line confirmation dialog. Calls saveChanges on the parent ec if the finalCommit flag is true. */ public WOActionResults deleteObjectWithFinalCommit(boolean finalCommit) { - dataSource().deleteObject(object()); EOEnterpriseObject obj = (EOEnterpriseObject)d2wContext().valueForKey(Keys.objectPendingDeletion); - obj.editingContext().deleteObject(obj); - + EODataSource ds = dataSource(); + + // check whether the relationship is marked "owns destination" + boolean isOwnsDestination = false; + if (ds != null && ds instanceof EODetailDataSource) { + EODetailDataSource dds = (EODetailDataSource) ds; + EOClassDescription masterClassDescription = dds.masterClassDescription(); + isOwnsDestination = masterClassDescription + .ownsDestinationObjectsForRelationshipKey(dds.detailKey()); + } + try { - obj.editingContext().saveChanges(); + // with EODetailDatasource, calling deleteObject + // will only remove the object from the relationship + ds.deleteObject(object()); + + // for "owns destination" relationships, the following would + // fail as the object will already be marked as deleted in the + // parent EC + if (!isOwnsDestination) { + // actually delete the object in the nested EC + obj.editingContext().deleteObject(obj); + obj.editingContext().saveChanges(); + } + if (displayGroup() != null && displayGroup().displayedObjects().count() == 0) { displayGroup().displayPreviousBatch(); }