Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#7841 closed defect (fixed)

JsonRestStore deleteItem deletes nothing in store

Reported by: syq Owned by: Kris Zyp
Priority: high Milestone: 1.3
Component: Data Version: 1.2.0
Keywords: JsonRestStore Cc:
Blocked By: Blocking:

Description

I use dijit.Tree with JsonRestStore?. After do store.deleteItem(old_item), and then save, the old_item is gone from tree and server database. Then I do store.newItem(new_item), both new_item and old_item appear. I check the store._index and find the old_item is still there. I am not certain if store._index is what causes the problem.

The store.deleteItem(old_item) actually does dojox.rpc.JsonRest?.deleteObject(old_item), which does not update the parent object of the old_item. So when do store.newItem(new_item), the getValues retrieves the children of old_item's parent which still includes the deleted old_item. This results in the deleted item reappearing on tree when adding a new item to the same parent of the deleted item.

Change History (7)

comment:1 Changed 11 years ago by Jared Jurkiewicz

Owner: changed from Jared Jurkiewicz to kriszyp

Looks like your JsonRestStore? has a problem with referential integrity (Removing an item referenced by other items doesn't clean up the other items). ItemFile?*Store had this issue at one time too, and was corrected by means of a reverse reference map. I'm not sure if JsonRestStore? can make use of the same technique, but it might be able to.

Take a look at functions:

_addReferenceToMap: function(/*item*/ refItem, /*item*/ parentItem, /*string*/ attribute){

summary: Method to add an reference map entry for an item and attribute. description: Method to add an reference map entry for an item and attribute. refItem: The item that is referenced. parentItem: The item that holds the new reference to refItem. attribute: The attribute on parentItem that contains the new reference.

_removeReferenceFromMap: function(/* item */ refItem, /* item */ parentItem, /*strin*/ attribute){

summary: Method to remove an reference map entry for an item and attribute. description: Method to remove an reference map entry for an item and attribute. This will also perform cleanup on the map such that if there are no more references at all to the item, its reference object and entry are removed. refItem: The item that is referenced. parentItem: The item holding a reference to refItem. attribute: The attribute on parentItem that contains the reference.

They're fairly simple overall and you may be able to plug in a similar tracking mechanism for JsonRestStore? so that a delete of an item will trigger item updates for items that had references to it.

comment:2 Changed 11 years ago by Kris Zyp

Jerod, I had intentionally omitted reference tracking from JsonRestStore? to reduce memory consumption and optimize performance. Stores users can manually remove references prior to deletion. I realize that IFWS has created an expectation of reference tracking and deletion "cascading" (removing references when an object is deleted), and agree that this is a nice feature, but I am not convinced that this is important enough to add to the intentionally lean OOTB module (maybe you can convince me otherwise). Perhaps this could be an extra module/trait (following your pattern in IFWS) that could optionally be used to augment a JRS. Kris

comment:3 in reply to:  2 Changed 11 years ago by syq

Kris, please comment if this is proper way to manually delete the reference.

  1. Find the parent item of the deleted_item, and remove the corresponding $ref: 'deleted_item_id' in its children array. This step will remove the reference.
  1. Remove the deleted_item from store._index in order to clean the garbage.

Also, I think it would reduce a lot of headache for the newbie like me who does not know the trick when using JsonRestStore? with widget. CRUD operation should better be transparent regardless of which store is used.

Thanks.

comment:4 Changed 11 years ago by Kris Zyp

Removing a reference can be done through a standard means, for regular property: store.unsetAttribute(parent, "child"); Removing a reference in a array: store.setValue(parent, store.getValues("childArray").concat().splice(3,1)); (note the concat is so the property is assigned a newly created array with the element removed).

It is true that JsonRestStore?? should remove the item from the _index map after receiving confirmation from the server after a successful transaction is completed. I will try to fix that, but that shouldn't have any observable semantic effects, only a slight memory leak for all but the most extreme delete-happy apps.

Mapping CRUD to objects does have inherent impedance mismatches. Allowing an operation on an object to have side effects on referencing objects is every bit as insidious in the object oriented world as not "cascading" deletes to references in the CRUD world. Consequently, I think it is best to ensure that you explicitly remove references to and delete objects at the same time, thus avoiding icky issue of dealing with references to deleted objects.

Hope this helps, please post any additional questions or suggestions.

comment:5 Changed 11 years ago by Jared Jurkiewicz

Owner: changed from kriszyp to Kris Zyp

comment:6 Changed 11 years ago by Kris Zyp

Resolution: fixed
Status: newclosed

JsonRestStore? now cleans up references when an item is deleted.

comment:7 Changed 11 years ago by Adam Peller

Milestone: tbd1.3

batch move of tickets marked 'tbd' fixed in the 1.3 timeframe

Note: See TracTickets for help on using tickets.