Re: RequestFactory/Editor AutoBean has been frozen error

322 views
Skip to first unread message

Tiago Rinck Caveden

unread,
Apr 19, 2012, 11:15:06 AM4/19/12
to google-we...@googlegroups.com
Hello all,

I tried to reply to the message below in its own thread (here: http://groups.google.com/group/google-web-toolkit/browse_thread/thread/4309e1e60f2cb8d8?pli=1 ), but I was getting an error at every attempt, so I decided to open a new topic with the same title.

It seems this useful workaround doesn't work anymore.
I get a ClassCastException when I try it. My RequestContext implementation is casted to AbstractRequestContext$State.
I can't find a way to access the state of a RequestContext in order to attribute the new one to the old AutoBean. The attribute is private. It almost seems somebody wanted to prevent this hack from being possible...

Is there any alternative now, besides manually copying each property of each proxy?

Thank you for any help,
Tiago.

On Feb 22 2011, 9:41 pm, Scott Olcott <scottolc...@gmail.com> wrote:
> 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.

--
Tiago Rinck Caveden

Brandon Donnelson

unread,
Apr 21, 2012, 11:48:39 PM4/21/12
to google-we...@googlegroups.com
I've has those too. I'm not sure there is enough source to diagnose. Do you have a list in your bean?

1. how do you init your driver?
2. do you have list that is null from server. 
3. do you have a list that is null when you start then you add to list then edit it again. always init a list as empty list. 
4. how are you creating your bean? then edit it?
5. are you using the same context for bean creation for lists that are children in the bean? 

I get more frozen errors with lists and how I init them, I always use the same context. 

Hope that helps,
Brandon Donnelson

Tiago

unread,
Apr 23, 2012, 4:29:35 AM4/23/12
to google-we...@googlegroups.com
Hello Brandon,

My problem isn't always "autobean is frozen", it changes, but the summary is that I cannot resubmit a proxy after a server error (like an unique constraint violation, for example) that ends up calling Receiver.onFailure().
The error I tend to get is DeadEntityException.

All I want is to be able to resubmit a proxy after a problem in the server. Recreate it is not an option because the user has already modified it, and I want to preserve the modifications. That's probably a common use case, I can't be the only one struggling with it, can I?

Answering your questions:

On Sunday, April 22, 2012 5:48:39 AM UTC+2, Brandon Donnelson wrote:
I've has those too. I'm not sure there is enough source to diagnose. Do you have a list in your bean?

1. how do you init your driver?

I init it in the view constructor.
 
2. do you have list that is null from server. 

I'm creating a new bean, in the current use case. (it's not coming from the server). There may be null/empty lists, yes.
 
3. do you have a list that is null when you start then you add to list then edit it again. always init a list as empty list. 

No.
 
4. how are you creating your bean? then edit it?

In this case, RequestContext.create, since it's a new entity. But I've stumbled upon this issue in cases where I was loading it from the server.

I use the same request context used to create the bean as parameter to the EditorDriver.edit method.

 
5. are you using the same context for bean creation for lists that are children in the bean? 


Not editing lists in this case.
 

I get more frozen errors with lists and how I init them, I always use the same context. 


I don't think my problem is particularly linked to lists, at least it doesn't look like. It is like the problem described in the original thread I linked to, I cannot reuse the proxies, nor I know an easy way to copy them - a workaround provided in the issue #5794 doesn't work for me as my graph has cycles, and the workaround provided in the linked discussion isn't working on 2.4 anymore, as it seems.

Thanks,
Tiago.

Thomas Broyer

unread,
Apr 23, 2012, 5:49:54 AM4/23/12
to google-we...@googlegroups.com


On Monday, April 23, 2012 10:29:35 AM UTC+2, Tiago wrote:
Hello Brandon,

My problem isn't always "autobean is frozen", it changes, but the summary is that I cannot resubmit a proxy after a server error (like an unique constraint violation, for example) that ends up calling Receiver.onFailure().
The error I tend to get is DeadEntityException.

All I want is to be able to resubmit a proxy after a problem in the server. Recreate it is not an option because the user has already modified it, and I want to preserve the modifications. That's probably a common use case, I can't be the only one struggling with it, can I?


In RequestFactory's design, onFailure is really an exception, and should never happen: errors should be conveyed as special return values. That doesn't quite change your issue here, as the proxy wouldn't be reusable either: that's because, again, RF has been designed with the idea that things shouldn't go wrong. For instance, unique constraint violations are not natural for (most / non-technical) users. Moreover, those kind of conditions should probably be detected as ConstraintVIolations so the user can "fix the proxy" and "resubmit his request".

Tiago

unread,
Apr 23, 2012, 8:57:09 AM4/23/12
to google-we...@googlegroups.com
Hello Thomas,

On Monday, April 23, 2012 11:49:54 AM UTC+2, Thomas Broyer wrote:
In RequestFactory's design, onFailure is really an exception, and should never happen: errors should be conveyed as special return values. That doesn't quite change your issue here, as the proxy wouldn't be reusable either: that's because, again, RF has been designed with the idea that things shouldn't go wrong. For instance, unique constraint violations are not natural for (most / non-technical) users. Moreover, those kind of conditions should probably be detected as ConstraintVIolations so the user can "fix the proxy" and "resubmit his request".

Could you help me a bit more by pointing to an example of what do you mean by "detected as ConstraintViolation"?
I have a situation where the user must attribute a reference value to an entity, and this value must be unique. I can only know if it's unique after my service is called and either I attempt an insert and treat the exception, or if I make a previous select before the insert (very low risk of concurrence issues for my case, I think I could safely ignore such risk). In either case, the request is already gone and the service has already been called. From what I understood by reading the previous thread I linked to, it is already too late to reuse the proxy.


By the way, I was not using onFailure as you say it should be used. I was using it for general business failures. We've even implemented a generic Receiver to deal with that. Not challenging what you say, but it really doesn't look like RF was built with the idea that errors should be treated in the return value... the return value most of the time is a proxy (or Collection of proxies) to an entity used in the back-end. Entities are not supposed to have request-specific error data. Basically, to operate like that, I would need different DTOs for every request, and proxy these DTOs, which would contain the needed entities plus error information. Is that how RF is supposed to be used?

Thank you,
Tiago.

Thomas Broyer

unread,
Apr 23, 2012, 10:21:50 AM4/23/12
to google-we...@googlegroups.com


On Monday, April 23, 2012 2:57:09 PM UTC+2, Tiago wrote:
Hello Thomas,

On Monday, April 23, 2012 11:49:54 AM UTC+2, Thomas Broyer wrote:
In RequestFactory's design, onFailure is really an exception, and should never happen: errors should be conveyed as special return values. That doesn't quite change your issue here, as the proxy wouldn't be reusable either: that's because, again, RF has been designed with the idea that things shouldn't go wrong. For instance, unique constraint violations are not natural for (most / non-technical) users. Moreover, those kind of conditions should probably be detected as ConstraintVIolations so the user can "fix the proxy" and "resubmit his request".

Could you help me a bit more by pointing to an example of what do you mean by "detected as ConstraintViolation"?
I have a situation where the user must attribute a reference value to an entity, and this value must be unique. I can only know if it's unique after my service is called and either I attempt an insert and treat the exception, or if I make a previous select before the insert (very low risk of concurrence issues for my case, I think I could safely ignore such risk). In either case, the request is already gone and the service has already been called. From what I understood by reading the previous thread I linked to, it is already too late to reuse the proxy.

You can use a custom JSR303 validator that does the select and the check; so that in case of a unique constraint violation, a ConstraintViolation would be sent back to the client (and in this case, the proxy is unfrozen so it can be "fixed" before firing the RequestContext again).
 
By the way, I was not using onFailure as you say it should be used. I was using it for general business failures. We've even implemented a generic Receiver to deal with that. Not challenging what you say, but it really doesn't look like RF was built with the idea that errors should be treated in the return value... the return value most of the time is a proxy (or Collection of proxies) to an entity used in the back-end. Entities are not supposed to have request-specific error data. Basically, to operate like that, I would need different DTOs for every request, and proxy these DTOs, which would contain the needed entities plus error information. Is that how RF is supposed to be used?

When your service method has "error paths", yes; but the main idea is that there should as few as possible.

Tiago

unread,
Apr 23, 2012, 11:56:58 AM4/23/12
to google-we...@googlegroups.com
On Monday, April 23, 2012 4:21:50 PM UTC+2, Thomas Broyer wrote:
You can use a custom JSR303 validator that does the select and the check; so that in case of a unique constraint violation, a ConstraintViolation would be sent back to the client (and in this case, the proxy is unfrozen so it can be "fixed" before firing the RequestContext again).

Interesting. I'll look into it.
Do you realize, though, that by doing this you will:
- Make at least one DB access more than what's strictly necessary. 
- Potentially run concurrence risks. If the risks are considerable, you may need pessimistic locks...

I feel uneasy with the potential overheads you add just due to the architecture. But, well, I guess until issue #5794 is not included, and if such overheads are not a big issue (and I bet they won't be for most people), that's probably the way to go.

 
When your service method has "error paths", yes; but the main idea is that there should as few as possible.


If you manage to filter everything via validators, then yeah, probably you won't have much more error paths to deal with. I wasn't using validators for anything needing DB access though.


Thank you again for your answers Thomas. Your help is much appreciated.


Best regards,
Tiago.
Reply all
Reply to author
Forward
0 new messages