bugGNUstep - Bugs: bug #8993, Broken validation causes problems...

Group
 
 

bug #8993: Broken validation causes problems with deleteObject:

Submitter:  Simon Stapleton <tufty>
Submitted:  Tue 18 May 2004 06:34:43 AM UTC
   
 
Category:  gdl2 Severity:  3 - Normal
Item Group:  Bug Status:  Fixed
Privacy:  Public Assigned to:  ayers
Open/Closed:  Closed
* Mandatory Fields

Add a New Comment Rich Markup
   

Tue 22 Jan 2008 04:42:50 PM UTC, comment #3: 

I've created a test case based on the description and current SVN seems to work as expected.

David Ayers <ayers>
Group Member
Wed 19 May 2004 05:15:35 PM UTC, comment #2: 

This is related to bug 3797
https://savannah.gnu.org/bugs/?func=detailitem&item_id=3797
and should be fixed with a large EOEditingContext patch I'm working on, which includes effectively a rewrite of the processRecentChanges mechanism.  Yet it may still take a bit until it is finished.  If this becomes an issue for someone else also, I'll consider interim hacks all the way up to deactivating the validation again.

David Ayers <ayers>
Group Member
Tue 18 May 2004 11:18:52 AM UTC, comment #1: 


> Then, during _processRecentChanges, we end up removing the object from
> both sides of its relationship to Person. this sets the personId to nil, using
> takeValue:forKey: and then any accessor that happens to be set for the
> attribute.


Actually, it's setPerson: which gets called, which calls (as it should) willChange.  My bad.  However, the net result is the same.

Simon Stapleton <tufty>
Tue 18 May 2004 06:34:43 AM UTC, original submission:  

Now that validation is being called when EOEditingContext does a saveChanges, a lt of things are fixed.  But a few others appear to be broken, notably validation on deleteObject:

What's required:

an existing EO with a mandatory to-one relationship

For example, I have Entity1, let's call it 'Person', which has a personId attribute.  I also have Entity2, called 'SalaryHistory'.  This also has a personId column.  Person has an optional to-many, owns destination, propagates primary key, cascades deletes relationship to SalaryHistory.  SalaryHistory has a mandary to-one relationsip to Person.

Now.  I want to delete an existing instance of SalaryHistory.  Let's assume I have it already.  My delete code looks like this:

id salaryHistory;
id editingContext;
... get the relevant EO into my EC.
NS_DURING
  {
    [editingContext deleteObject:salaryHistory];
    [editingContext saveChanges];
  }
NS_HANDLER
  [localException raise];
NS_ENDHANDLER

What happens is this:

We mark the object for deletion.  This puts it into _unprocessedDeletes
Then, during _processRecentChanges, we end up removing the object from both sides of its relationship to Person.  this sets the personId to nil, using takeValue:forKey: and then any accessor that happens to be set for the attribute.
As a result of this, the object ends up invoking [self willChange], and it gets stuffed into _unprocessedChanges as well.
A little later, we end up calling [EOEditingContext validateChanges].  This happily lets the delete through, but barfs on the spurious change, as the object has no valid key for the obligatory to-one.  So we raise an exception.

There appear to be two ways to fix this.

One might be to have removeObject:fromBothSidesOfRelationshipWithKey: to use takeStoredValue:forKey:, but that would blow normal validation where the object is actually being changed, not deleted.  Fiddling with this is likely to get complex, and fast.

The approach I have taken is to change [EOEditingContext propagatesDeletesUsingTable:] to this:

- (void) propagatesDeletesUsingTable: (NSHashTable*)deleteTable
                         changeTable: (NSHashTable*)changeTable
{
  NSHashEnumerator enumerator;
  id object = nil;

  EOFLOGObjectFnStart();

  enumerator = NSEnumerateHashTable(deleteTable);

  while ((object = (id)NSNextHashEnumeratorItem(&enumerator))) {
    [object propagateDeleteWithEditingContext: self];
    NSHashRemove(changeTable, object);  // Remove the object if it's been added to the change table
  }

  EOFLOGObjectFnStop();
}

and the call in _processDeletedObjects to this:

  [self propagatesDeletesUsingTable: _unprocessedDeletes
        changeTable: _unprocessedChanges];

Which seems to solve the problem.

Simon Stapleton <tufty>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by ayers (Posted a comment)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2008-01-22 ayers StatusNone Fixed
        Open/ClosedOpen Closed
    2004-05-19 ayers Assigned toNone ayers

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code