If after clearing the undo stack I open a dummy undo group i.e.
undoManager().removeAllActions();
undoManager().beginUndoGrouping();
Then things do seem to run ok, so there is a dummy undoGrouping for the java
client server side request handling code to close off, but seems a bit
outlandish to do this, asking for more future problems?
John
On 10 Oct 2014, at 10:40, John Pollard <[email protected]> wrote:
> I instead used the property er.extensions.ERXEC.editingContextClassName to
> specify the ForgetfulEC which I had change to be subclassed from ERXEC
>
> However, with the call to undoManager().removeAllActions() seems to tread on
> some toes; a later endUndoGrouping() called by some other code is now falling
> over with this exception...
>
> - <er.extensions.appserver.ERXComponentRequestHandler>: Exception occurred
> while handling request:
> java.lang.IllegalStateException: endUndoGrouping: undo manager is in invalid
> state, endUndoGrouping called with no matching begin
> Oct 10 09:33:25 InraxServer[8888] DEBUG NSLog - Handle Application Exception
> Reporting exception at: 09:33
> From: Application.handleException()
>
> Original Request IP: 192.168.0.124 URI:
> /cgi-bin/WebObjects/InraxServer.woa/-8888/wo/0g6rgMRRb2p4aTaQYIIW7g/0.1.0.1.0
> Session: 0g6rgMRRb2p4aTaQYIIW7g
>
> Component: com.webobjects.eodistribution.WOJavaClientApplet
>
> Exception message: endUndoGrouping: undo manager is in invalid state,
> endUndoGrouping called with no matching begin
>
> Stack Trace...
>
> java.lang.IllegalStateException: endUndoGrouping: undo manager is in invalid
> state, endUndoGrouping called with no matching begin
> at
> com.webobjects.foundation.NSUndoManager.endUndoGrouping(NSUndoManager.java:565)
> at
> com.webobjects.eodistribution.EODistributionContext.responseToClientMessage(EODistributionContext.java:626)
> at
> com.webobjects.eodistribution.WOJavaClientApplet.handleClientRequest(WOJavaClientApplet.java:978)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> ...
>
>
>
> On 10 Oct 2014, at 09:50, John Pollard <[email protected]> wrote:
>
>> Thanks, I will give this a try.
>> I am using Java Client, not sure about the "applets" bit.
>> Currently the client session ec is created using
>> ERXEC.newEditingContext(objStore)
>> So should I...
>> Create a sublcass of ERXEC.DefaultFactory and override
>> _createEditingContext() in it, to return a ForgetfulEC
>> Install my factory using ERXEC.setFactory()
>> Anything else?
>> Thanks
>> John
>>
>> On 9 Oct 2014, at 17:27, Chuck Hill <[email protected]> wrote:
>>
>>> First question, are you using JavaClient applets?
>>>
>>> Below is a Java class that might both explain and solve what you are seeing.
>>>
>>>
>>> Chuck
>>>
>>>
>>> package net.global_village.eofextensions;
>>>
>>> import com.webobjects.eocontrol.*;
>>>
>>> /**
>>> * EOEditingContext that clears undo stack after a successful save. This
>>> is used as a work around for a bug in EOF. There is a rather serious bug
>>> when validateForDelete() fails to allow a deletion. This will occur if you
>>> are using the Deny delete rule, the relationship is mandatory, or you have
>>> a custom validateForDelete() method. The error occurs in this scenario:<br>
>>> * 1. The editing context has multiple generations, meaning that
>>> saveChanges() has been called one or more times after one or more EOs has
>>> been created / inserted / updated.<br>
>>> * 2. An EO is deleted from the editing context by deleteObject().<br>
>>> * 3. saveChanges() fails due to an NSValidation.ValidationException raised
>>> in validateForDelete.<br>
>>> *
>>> * This result of this appears to be that undo() is called on the editing
>>> context's undo manager too many times. Instead of rolling back to the
>>> state when saveChanges() was called it rolls back past several of previous
>>> saveChanges()! The result of this is that the editing context shows a
>>> historical state that does not match the object store or the database.
>>> *
>>> * @author Copyright (c) 2001-2005 Global Village Consulting, Inc. All
>>> rights reserved.
>>> * This software is published under the terms of the Educational Community
>>> License (ECL) version 1.0,
>>> * a copy of which has been included with this distribution in the
>>> LICENSE.TXT file.
>>> * @version $Revision: 7$
>>> */
>>> public class ForgetfulEC extends EOEditingContext
>>> {
>>>
>>>
>>> /**
>>> * Designated constructor. Creates a new ForgetfulEC object with
>>> anObjectStore as its parent
>>> * object store.
>>> *
>>> * @param anObjectStore parent object store
>>> */
>>> public ForgetfulEC(EOObjectStore anObjectStore)
>>> {
>>> super(anObjectStore);
>>> }
>>>
>>>
>>>
>>> /**
>>> * Creates a new ForgetfulEC object with the default parent object
>>> store as its parent object
>>> * store.
>>> */
>>> public ForgetfulEC()
>>> {
>>> super();
>>> }
>>>
>>>
>>>
>>> /**
>>> * Overridden to clear undo stack after a successful save.
>>> */
>>> public void saveChanges()
>>> {
>>> super.saveChanges();
>>> if (undoManager() != null)
>>> {
>>> undoManager().removeAllActions();
>>> }
>>> }
>>>
>>> }
>>>
>>>
>>> On 2014-10-09, 7:22 AM, "John Pollard" wrote:
>>>
>>> My trap set up in takeStoredValueForKey() for my intermittent has triggered
>>> reporting my bug where an attribute is being set to null. However, the
>>> stack trace below doesn't come from anywhere obvious in my code. It is
>>> server side processing a client request and for some reason there is an
>>> "undo" being triggered from WOJavaClientApplet.handleClientRequest()
>>>
>>> My trap fires off when the attribute is being changed from a non-null value
>>> to a null value, which should never happen, but it is.
>>>
>>> Furthermore, in my trap I make sure I don't call
>>> super.takeStoredValueForKey() if I can see the attribute is about to be set
>>> to null...but somehow the value is still being set to null on the database.
>>>
>>> Any thoughts welcome!
>>>
>>> John
>>>
>>> at mp.gen.Utils.getStackTraceAsString(Utils.java:2819)
>>> at mp.eo.Transaction.takeStoredValueForKey(Transaction.java:1920)
>>> at
>>> com.webobjects.eocontrol.EOCustomObject.updateFromSnapshot(EOCustomObject.java:581)
>>> at
>>> er.extensions.eof.ERXGenericRecord.updateFromSnapshot(ERXGenericRecord.java:1267)
>>> at
>>> com.webobjects.eocontrol.EOEditingContext._undoUpdate(EOEditingContext.java:1629)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>> at java.lang.reflect.Method.invoke(Method.java:622)
>>> at com.webobjects.foundation.NSSelector.invoke(NSSelector.java:358)
>>> at
>>> com.webobjects.foundation.NSSelector._safeInvokeSelector(NSSelector.java:110)
>>> at
>>> com.webobjects.foundation.NSUndoManager$_NSUndoLightInvocation.invoke(NSUndoManager.java:1002)
>>> at
>>> com.webobjects.foundation.NSUndoManager$_NSUndoStack.popAndInvoke(NSUndoManager.java:1280)
>>> at
>>> com.webobjects.foundation.NSUndoManager.undoNestedGroup(NSUndoManager.java:733)
>>> at com.webobjects.foundation.NSUndoManager.undo(NSUndoManager.java:693)
>>> at
>>> com.webobjects.eodistribution.EODistributionContext.responseToClientMessage(EODistributionContext.java:627)
>>> at
>>> com.webobjects.eodistribution.WOJavaClientApplet.handleClientRequest(WOJavaClientApplet.java:978)
>>> at sun.reflect.GeneratedMethodAccessor33.invoke(Unknown Source)
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>> at java.lang.reflect.Method.invoke(Method.java:622)
>>> at
>>> com.webobjects.foundation.NSKeyValueCoding$ValueAccessor$1.methodValue(NSKeyValueCoding.java:636)
>>> at
>>> com.webobjects.foundation.NSKeyValueCoding$_MethodBinding.valueInObject(NSKeyValueCoding.java:1134)
>>> at
>>> com.webobjects.foundation.NSKeyValueCoding$DefaultImplementation.valueForKey(NSKeyValueCoding.java:1324)
>>> at com.webobjects.appserver.WOComponent.valueForKey(WOComponent.java:1736)
>>> at
>>> com.webobjects.foundation.NSKeyValueCoding$Utility.valueForKey(NSKeyValueCoding.java:447)
>>> at
>>> com.webobjects.foundation.NSKeyValueCodingAdditions$DefaultImplementation.valueForKeyPath(NSKeyValueCodingAdditions.java:212)
>>> at
>>> com.webobjects.appserver.WOComponent.valueForKeyPath(WOComponent.java:1804)
>>> at
>>> com.webobjects.appserver._private.WOKeyValueAssociation.valueInComponent(WOKeyValueAssociation.java:50)
>>> at
>>> com.webobjects.appserver._private.WOGenericElement.invokeAction(WOGenericElement.java:121)
>>> at
>>> com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:105)
>>> at
>>> com.webobjects.appserver._private.WOGenericContainer.invokeAction(WOGenericContainer.java:29)
>>> at
>>> com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:105)
>>> at
>>> com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:115)
>>> at
>>> com.webobjects.appserver._private.WOConditional.invokeAction(WOConditional.java:86)
>>> at
>>> com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:105)
>>> at
>>> com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:115)
>>> at com.webobjects.appserver.WOComponent.invokeAction(WOComponent.java:1079)
>>> at
>>> com.webobjects.appserver._private.WOComponentReference.invokeAction(WOComponentReference.java:127)
>>> at
>>> com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:105)
>>> at
>>> com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:115)
>>> at com.webobjects.appserver.WOComponent.invokeAction(WOComponent.java:1079)
>>> at com.webobjects.appserver.WOSession.invokeAction(WOSession.java:1357)
>>> at
>>> com.webobjects.appserver.WOApplication.invokeAction(WOApplication.java:1745)
>>> at
>>> er.extensions.appserver.ajax.ERXAjaxApplication.invokeAction(ERXAjaxApplication.java:119)
>>> at
>>> er.extensions.appserver.ERXApplication.invokeAction(ERXApplication.java:1988)
>>> at
>>> er.extensions.appserver.ERXComponentRequestHandler._dispatchWithPreparedPage(ERXComponentRequestHandler.java:157)
>>> at
>>> er.extensions.appserver.ERXComponentRequestHandler._dispatchWithPreparedSession(ERXComponentRequestHandler.java:235)
>>> at
>>> er.extensions.appserver.ERXComponentRequestHandler._dispatchWithPreparedApplication(ERXComponentRequestHandler.java:268)
>>> at
>>> er.extensions.appserver.ERXComponentRequestHandler._handleRequest(ERXComponentRequestHandler.java:302)
>>> at
>>> er.extensions.appserver.ERXComponentRequestHandler.handleRequest(ERXComponentRequestHandler.java:378)
>>> at
>>> com.webobjects.appserver.WOApplication.dispatchRequest(WOApplication.java:1687)
>>> at
>>> er.extensions.appserver.ERXApplication.dispatchRequestImmediately(ERXApplication.java:2109)
>>> at
>>> er.extensions.appserver.ERXApplication.dispatchRequest(ERXApplication.java:2074)
>>> at mpServer.Application.dispatchRequest(Application.java:168)
>>> at
>>> com.webobjects.appserver._private.WOWorkerThread.runOnce(WOWorkerThread.java:144)
>>> at
>>> com.webobjects.appserver._private.WOWorkerThread.run(WOWorkerThread.java:226)
>>> at java.lang.Thread.run(Thread.java:701)
>>> On 12 Sep 2014, at 09:18, John Pollard <[email protected]> wrote:
>>>
>>>> Hmm, hairy palms, not sure I want that, but thanks for this anyway. The
>>>> related attribute is a to-one relationship, does that mean it is a FK
>>>> attribute? It is the to-one relationship that becomes null against my will
>>>> and I need to find out where/why.
>>>>
>>>> I have now cobbled some code up in takeStoredValueForKey() which avoids
>>>> the recursion when checking the existing value using storedValueForKey()
>>>> and ignores the (temp) null value caused by clearProperties() when the EO
>>>> is invalidated. Hence I believe I now have the code to scream if my
>>>> property is set to null from a pre-existing value and I should get an
>>>> email + stack trace to report the exciting news. These intermittents are
>>>> about once every two months so will have to wait.
>>>>
>>>> On 11 Sep 2014, at 23:04, Chuck Hill <[email protected]> wrote:
>>>>
>>>>> You are going to grow hair on your palms doing this but…
>>>>>
>>>>> willRead();
>>>>> Object value = __dictionary().valueForKey(“your attribute”);
>>>>>
>>>>> Should, I think, do what you want. Of course, it is package protected so
>>>>> you will need to use reflection to get access. And the result may be
>>>>> null if the object is still a fault.
>>>>>
>>>>> Is this an FK or PK by chance?
>>>>>
>>>>>
>>>>> Chuck
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On 2014-09-11, 12:22 PM, "John Pollard" wrote:
>>>>>
>>>>> Apologies, I meant takeStoredValueForKey(). Within there, how can I
>>>>> safely see what the value currently is when when this method is called,
>>>>> before I invoke super. takeStoredValueForKey() to take on the new value?
>>>>> John
>>>>>
>>>>> On 11 Sep 2014, at 18:10, John Huss <[email protected]> wrote:
>>>>>
>>>>>> The order of calls is:
>>>>>>
>>>>>> takeValueForKey -> setXXX -> takeStoredValueForKey
>>>>>>
>>>>>> All of these maybe skipped except for takeStoredValueForKey, so that is
>>>>>> the only one you should override to see what is getting saved.
>>>>>>
>>>>>>
>>>>>> On Thu, Sep 11, 2014 at 8:55 AM, John Pollard <[email protected]>
>>>>>> wrote:
>>>>>> Hi List,
>>>>>>
>>>>>> In some debugging within takeValueForKey() I want to find out if the key
>>>>>> already has a value set. If I call valueForKey() or storedValueForKey()
>>>>>> and the value isn't already set I get infinite recursion as it triggers
>>>>>> a fault and tries to load with takeValueForKey() and so on.
>>>>>>
>>>>>> I am trying to debug where a value is being set to null, but apparently
>>>>>> not going via validateXXX() or setXXX() methods, so I want to trap the
>>>>>> case where the takeValueForKey() is passed null when the key value was
>>>>>> previously non-null and log a stack trace.
>>>>>>
>>>>>> Thanks
>>>>>> John
>>>>>> _______________________________________________
>>>>>> Do not post admin requests to the list. They will be ignored.
>>>>>> Webobjects-dev mailing list ([email protected])
>>>>>> Help/Unsubscribe/Update your Subscription:
>>>>>> https://lists.apple.com/mailman/options/webobjects-dev/johnthuss%40gmail.com
>>>>>>
>>>>>> This email sent to [email protected]
>>>>>>
>>>>>
>>>>
>>>
>>
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list ([email protected])
>> Help/Unsubscribe/Update your Subscription:
>> https://lists.apple.com/mailman/options/webobjects-dev/john%40pollardweb.com
>>
>> This email sent to [email protected]
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list ([email protected])
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/webobjects-dev/john%40pollardweb.com
>
> This email sent to [email protected]
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [email protected]