RequestFactory/Editor AutoBean has been frozen error

885 views
Skip to first unread message

Scott Olcott

unread,
Feb 17, 2011, 5:39:02 PM2/17/11
to Google Web Toolkit
I am trying to use the RequestFactory and Editor frameworks together.
I have it working successfully for requests that finish successfully
or that result in constraint violations. However, whenever there are
server errors and my Receiver.onFailure(ServerFailure) method is
called I am not able to reuse my proxy object.

If I do nothing in the onFailure method other that setting the some
error message in the ui and then try to fire another request using the
same proxy object I get the AutoBean has been frozen error message.
When there are contraint violations I can successfully fire another
request with the same proxy object. After digging into the code I
found the doFire method in AbstractRequestContext. Inside this method
it creates an anonymous TransportReceiver object which handles the
response from the server.

TransportReceiver.onTransportSuccess(String payload) handles an
response that successfully hit the server. If
response.getGeneralFailure() != null or there are constraint
violations AbstractRequestContext.reuse() is eventually called which
unfreeze any autobean entities that were apart of the request and
unlocked the request context.

However on errors that aren't generalFailures reuse() is never
called. This means that this instance of the autobean can never be
used again without getting the Autobean is frozen error. Has anyone
else run into this issue. If so is there a workaround for it.

Thanks

Scott Olcott

unread,
Feb 17, 2011, 5:48:05 PM2/17/11
to Google Web Toolkit
I am using GWT 2.2

Scott Olcott

unread,
Feb 18, 2011, 1:45:16 PM2/18/11
to google-we...@googlegroups.com
I have temporarily fixed this by copying AbstractRequestContext into a super-source directory and making the change there.  I also had to call invocations.clear() to avoid duplicate invocations the next time a request is fired.  You also need to make sure editedProxies.clear() is not called otherwise all the properties on your proxy will be null on the next request.

It looks like invocations.clear() should also be called when there are violations, otherwise you will get duplicate invocations.  I noticed this on the violations because it would display duplicated error messages on the second request. 

Thomas Broyer

unread,
Feb 18, 2011, 7:01:14 PM2/18/11
to google-we...@googlegroups.com
I think it was on-purpose: validation is done before any invocation is processed, so you can safely send the same invocations back to the server after making changes to the proxies so they validate the next time. I guess the idea is that you then only change proxies and fire the context again, without enqueueing your invocations once more.

Failures however can happen at any time during invocations processing. Clearing invocations would work in many cases, but not all: you'll send the same operations, but the domain objects might have change as a result of a previous successful invocation (RequestFactory doesn't make any assumption on the use of transactions, so things have not necessarily been rolled back; actually in your case, our datastore –MongoDB– doesn't have that concept of transaction, and we successfully use RF with it; and similarly, AppEngine transactions are so specific that you won't enclose your whole RF request in a transaction), so applying the operations might very well fail (e.g. entity has been deleted, or its state has changed so that a setter now throws an exception).

You'd probably rather want to copy the edited entities to another context. I haven't checked but it might be possible using AutoBeanUtils.getAutoBean and AutoBean.clone before a context.edit().

Colin Alworth

unread,
Feb 19, 2011, 9:26:35 PM2/19/11
to google-we...@googlegroups.com
I think you are addressing the wrong issue – Scott is pointing out that general exceptions do not allow you to re-fire contexts after modifying the proxies further. The r/o proxy instance is stuck as read only because there still exists a context-specific edited copy of it, which did not succeed and has not been cleared.

The context clears itself in the case of failure or validation error, but not in the case of general failure, Scott is suggesting (and I think I agree, admittedly without having tried this use case) that this is a mistake, and that general transport failure should be treated as something that can be retried.

Thomas Broyer

unread,
Feb 20, 2011, 5:16:41 AM2/20/11
to google-we...@googlegroups.com


On Sunday, February 20, 2011 3:26:35 AM UTC+1, Colin Alworth wrote:
I think you are addressing the wrong issue – Scott is pointing out that general exceptions do not allow you to re-fire contexts after modifying the proxies further.

Given his last message, about clearing 'invocations' but not clearing 'editedProxies', I think I was understanding correctly: I understand it as "I want to be able to fire the same context again, so the edits made to proxies are not lost, but I have to clear invocations otherwise, because I'll enqueue my invocations again, my service methods on the server side will be called twice".
 
The r/o proxy instance is stuck as read only because there still exists a context-specific edited copy of it, which did not succeed and has not been cleared.

The context clears itself in the case of failure or validation error, but not in the case of general failure, Scott is suggesting (and I think I agree, admittedly without having tried this use case) that this is a mistake, and that general transport failure should be treated as something that can be retried.

I'm reading the code in trunk@9753 but I believe there hasn't been much changes since 2.2 (apart from the refactoring when introducing JsonRpc support):
  • onTransportFailure, fail() is called, which calls reuse(), so the same context can be fire()d again.
  • on general failure, fail() is called too
  • on violation, violation() is called, which calls reuse()
reuse() unfreezes the proxies that have been edit()ed in this context, so you can edit them further (in the same context), and unlocks the context (so you can fire() it again).

This means that on transport failure and general failure, you can just call fire() again to retry. And on violation, you can fix the errors and then fire() to try again.

In case of "non general" failure though, the onFailure method of the associated invocation's Receiver will be called but everything else will be as if all was OK (the context-level Receiver's onSuccess is called, the context is still frozen so it cannot be reused, and editedProxies is cleared so the proxies can be edit()ed in other contexts).

Am I wrong in my reading and understanding of the code?

Scott Olcott

unread,
Feb 22, 2011, 2:41:21 PM2/22/11
to google-we...@googlegroups.com
Thomas,
You are correct in understanding my issue.  I tried calling AutoBean.clone(), but is fails with a "Cannot clone wrapped bean" error.

I was however able to resubmit the proxy successfully using the following:

        AutoBean<Test> autoBean = AutoBeanUtils.getAutoBean(test);

        autoBean.setFrozen(false);

        requestContext = requestFactory.testRequest();

        autoBean.setTag("requestContext", requestContext);

        driver.edit(test, requestContext);


calling autoBean.setTag("requestContext", requestContext) is needed to avoid a "Attempting to edit an EntityProxy previously edited by another RequestContext"  error.  I know it's a hack but it's the only thing I can get to work other than copying the proxy into a new proxy property by property.



bloo

unread,
Dec 9, 2011, 12:20:40 AM12/9/11
to google-we...@googlegroups.com
Hi, I'm glad I found this thread as I've run into the same pattern.  Is the AutoBean hack on onFailure still required, as of 2.4.0?  Or is there a more elegant control to be able to reuse the RequestContext and EntityProxy?

Thomas Broyer

unread,
Dec 9, 2011, 4:25:13 AM12/9/11
to google-we...@googlegroups.com
It's "by design", so nothing has changed in 2.4; and http://code.google.com/p/google-web-toolkit/issues/detail?id=5794 hasn't yet been fixed (patches welcome! ;-) ).
Reply all
Reply to author
Forward
0 new messages