Once you get information about the changes made to enterprise objects in an editing context as described in “Getting Information About Changed Objects,” you may want to undo those changes. By invoking undo on an editing context, the latest set of changes to enterprise objects in that editing context are reversed. You can invoke the method redo to reverse the latest undo operation. You can invoke the method revert to discard all changes in an editing context, including all insertions and deletions. This restores changes to updated objects to their last committed values (their values in the database). An even more severe undo operation is possible using the reset method, which clears all enterprise objects in the editing context.
You may wonder what the scope of an undo operation is. When you invoke undo on an editing context, how much is undone? The scope of an undo in Enterprise Objects is event-based. In a WebObjects application, a single request in the request-response loop constitutes an event. In a Java Client application, a single user event such as a mouse click or menu choice that invokes an operation constitutes an event. The change of a single value in an enterprise object doesn’t constitute an event, unless the change is triggered by an atomic event of either of these types. This undo scope ensures that anytime undo is invoked, the object graph returns to a stable state.
The undo support in EOEditingContext is arbitrarily deep for editing contexts that you create programmatically; you can undo an object repeatedly until you restore it to the state it was in when it was first created or fetched into its editing context. Starting with WebObjects 5.2, the default editing context in WOSession objects limits the number of undo operations to 10.
Even after an editing context’s changes are committed to a database, you can undo a change. To support this feature, the undo manager (an instance of NSUndoManager) can consume a lot of memory.
For example, whenever an object is removed from a relationship, the corresponding editing context creates a snapshot of the modified source object. The snapshot, which references the removed object, is referenced by both the editing context and the undo manager. The editing context releases the reference to the snapshot when the change is saved, but the undo manager doesn’t. The undo manager continues holding the snapshot so it can undo the deletion upon request.
The usage patterns of your applications may cause the undo manager to consume an unreasonable amount of memory. A common design pattern to limit an undo manager’s memory use is to clear an undo manager’s stack when an editing context saves. The most severe consequence of this it that it prevents undo beyond the point of saving. To do this, invoke the method removeAllActions on an editing context’s undo manager after invoking saveChanges. You can also set maximum levels of undo using the method setLevelsOfUndo. Or, if an application or editing context doesn’t require an undo manager, you can set an editing context’s undo manager to null with the method setUndoManager.
Last updated: 2007-07-11